How do I avoid a "dangling" newline when reading single character user input?


Match word(s).

If you have any questions or comments,
please visit us on the Forums.

FAQ > How do I... (Level 2) > How do I avoid a "dangling" newline when reading single character user input?

This item was added on: 2012/11/08

To get a single character from the user in C, many beginning programmers use either scanf() with the format specifier %c or getchar(). Both functions read a character from the standard input stream (the difference between them is that getchar() returns an int, whereas scanf() expects a pointer to char).

But both have the same pitfall: when the user enters a character s/he afterwards presses the enter key. Thus there are actually two characters in the input stream: the character entered and the newline character.
If you don't remove the newline character from the input stream, it could interfere with input functions later in the program. It seems that the input is ignored.
For example, look at the following program:


#include

int main(void)
{
char ch;

do
{
printf("Enter a letter (q to quit): ");
scanf("%c", &ch);
printf("You've entered >>%c<<\n", ch);
} while (ch != 'q');
printf("Character left in the input stream: >>%c<<\n", getchar());
return 0;
}

/* A sample session:
Enter a letter (q to quit): a
You've entered >>a<<
Enter a letter (q to quit): You've entered >>
<<
Enter a letter (q to quit): b
You've entered >>b<<
Enter a letter (q to quit): You've entered >>
<<
Enter a letter (q to quit): q
You've entered >>q<<
Character left in the input stream: >>
<<
*/

As you can see, every second scanf() call doesn't wait for new input but reads the newline character which is still left in the stream. Only then the stream is empty and the program has to wait for the user to get new input. Note also that after quitting the loop with "q", the newline character is still left behind and could affect a character reading function later in the program!

There are several workarounds:
For a simple solution, you could add a space before the format specifier when you use scanf(), for example:

scanf(" %c", &ch);

The leading space tells scanf() to skip any whitespace characters (including newline) before reading the next character, resulting in the same behavior as with the other format specifiers.

You could also use getchar() after a scanf()/getchar() call to remove the newline character. Similarly you could use

scanf("%c%*c", &ch);

which will read two characters, storing the first in "ch" and throwing away the second. Both solutions only work if you are sure the next character to read will be '\n'.

All three workarounds mentioned above aren't very stable. Consider the case when the user enters more than one character (by accident or on purpose). They will all fail in that situation.

A better approach is flushing the input buffer after every scanf()/getchar() call, but don't use fflush(stdin)!

Or, depending on your requirements, you could also forget about scanf()/getchar(), use fgets() to get a line of text from the user and parse it yourself.

Script provided by SmartCGIs