The easiest way in ISO C to read a whole line of input is to use the function fgets
.
The user can enter any amount of text. (Any excess text can be truncated, or some other sensible default behavior.)
That is where is gets complicated. The easiest solution would simply report failure if it detects that the line is too long to fit in the buffer:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
//This function will return true on success, false on failure.
//The buffer must be two bytes larger than the actual length of
//the line. It needs an extra byte for the newline character
//(which will be removed) and for the terminating null
//character.
bool get_line_from_user( char *buffer, int buffer_size )
{
char *p;
if ( fgets( buffer, buffer_size, stdin ) == NULL )
{
fprintf( stderr, "Error reading from input\n" );
return false;
}
//make sure that entire line was read in (i.e. that
//the buffer was not too small)
if ( ( p = strchr( buffer, '\n' ) ) == NULL )
{
//a missing newline character is ok on end-of-file condition
if ( !feof( stdin ) )
{
int c;
fprintf( stderr, "Line input was too long!\n" );
//discard remainder of line
do
{
c = getchar();
if ( c == EOF )
{
fprintf( stderr, "Error reading from input\n" );
return false;
}
} while ( c != '\n' );
return false;
}
}
else
{
//remove newline character by overwriting it with null character
*p = '\0';
}
return true;
}
int main( void )
{
char line[20];
printf( "Please enter a line of input:\n" );
if ( get_line_from_user( line, sizeof line ) )
{
printf( "Input was valid. The input was:\n%s", line );
}
else
{
printf( "Input was invalid." );
}
}
This program has the following behavior:
Valid input:
Please enter a line of input:
This is a test.
Input was valid. The input was:
This is a test.
Input too long:
Please enter a line of input:
This is a test line that is too long to fit into the input buffer.
Line input was too long!
Input was invalid.
Of course, a buffer size of only 20 is obviously too small for most common tasks. I only set it this low in order to demonstrate the error message. Normally, I would set the buffer size to, maybe, 200.
Under most circumstances, it should be no problem to increase the buffer size to several kilobytes if necessary, even if the buffer is being allocated on the stack.
If you want to be able to read more than a few kilobytes in a single line (for example if the input is being redirected from a file), then it would probably be better to allocate a sufficiently sized array that is on the heap instead of the stack, by using the function malloc
.
If you want the maximum line size to be truly unlimited, then you could call the function fgets
multiple times per line, until it encounters the newline character, and resize the buffer as necessary. See this question for further information (credit goes to the comments section for this link).
ADDITIONAL NOTE: The fgets() function is also not what I'm looking for. If a user enters more text than is allocated for the buffer, then the remainder of the text is automatically used the next time fgets() is called.
That is why my program discards the remainder of the line from the input stream, if it detects that the line was too long. That way, you do not have this problem.