Search code examples
cstdinfgetsgetchar

C - Using getchar over fgets for stdin


New here,

Is there any disadvantage to using getchar() method as opposed to fgets() for reading a string, other than the fact that getchar() reads just from stdin where as we can choose a stream for fgets().

Assuming, I have to only work with stdin, is there a reason why I should or shouldn't choose one or the other?

The one advantage I see for getchar() is that fgets() requires us to specify the maximum characters that can be read in advanced, whereas we can use a buffer in case of getchar() to store the string and reallocate as per our need.

[ EDIT ]

I implemented this function to read inputs, but is there any reason to do so when fgets() could also suffice if the length of the string is known.

char *scanner ( const char *text )
{
    char *buffer = ( char * ) malloc ( sizeof ( char ) * BUFFER_SIZE );

    int token;
    int length = 0;
    int limit = BUFFER_SIZE;

    printf("%s", text);

    while ( ( token = getchar ( ) ) != '\n' && token != EOF )
    {
        buffer [ length ++ ] = token;

        if ( length > limit )
        {
            limit += 256;
            buffer = ( char * ) realloc ( buffer, sizeof ( char ) * limit );
        }
    }

    buffer [ length ] = '\0';

    return buffer;
}

Solution

  • Is there any disadvantage to using getchar() method as opposed to fgets() for reading a string, other than the fact that getchar() reads just from stdin where as we can choose a stream for fgets().

    Yes.

    • fgets() requires only one call in the general case, and it handles recognizing end-of-line automatically. getchar() needs to be called in a loop in the general case, and you need to handle line-termination recognition yourself. That makes getchar() both more complicated to use and more costly for the purpose.

    • Furthermore, if there is more than one place in your program where you want to read strings, you would want to put any getchar()-based solution into a function so that you can reuse it, and then you're straight to your own reimplimentation of fgets anyway.

    • It is also reasonable to expect the experts who wrote and tuned your C library to have implemented fgets() more efficiently than you can reasonably expect to match by rolling your own with getchar().

    The one advantage I see for getchar() is that fgets() requires us to specify the maximum characters that can be read in advanced, whereas we can use a buffer in case of getchar() to store the string and reallocate as per our need.

    If you mean that using getchar() allows you to reallocate on a character-by-character basis then

    1. Technically, you can get that with fgets(), too.
    2. You generally want to perform (re)allocation in larger chunks, because it is expensive. And you can do that in conjunction with fgets, too.