How to grab an input line from stdin

Last update: 2010-03-27

Description

Sometimes you need to grab some characters from stdin. The user confirms the end of the input by pressing the Enter-key. The Enter-key is interpreted as a special character named newline ('\n'). The libc offers different functions to read characters from the stdin stream. One read the stream until a newline character is found and copy all characters excluding the newline to a string. This comes in handy when you don't need that character anyway, e.g. to process names.

gets() does exactly this, but you shall not use this function anymore! It's evil, because it doesn't know, nor checks the size of a given string and therefore alleviates the inclusion of severe bugs, potentially provoking buffer overflows.

fgets() does principally the same, but guarantees not to write more characters than the number of size you provide. Hence it is - when used correctly - more secure than gets() alone. But, and that's probably the occasion of this writing, fgets() appends a newline character to the string, if it finds one.

Take a second and write a wrapper function like the following to "prevent" that. (Yeah, it doesn't actually prevent that behaviour, it "retouches" it.

char * my_fgets(char *s, int size, FILE *stream)
{
        char *p;

        if (!(fgets(s, size, stream)))
	        return NULL;

        if ((p = strchr(s, '\n')))
                *p = '\0';

        return s;
}

This function behaves just like the standard C89 fgets(), but nullifies a newline character if necessary.