I have the following program:
int main(int argc, char *argv[])
{
char ch1, ch2;
printf("Input the first character:"); // Line 1
scanf("%c", &ch1);
printf("Input the second character:"); // Line 2
ch2 = getchar();
printf("ch1=%c, ASCII code = %d\n", ch1, ch1);
printf("ch2=%c, ASCII code = %d\n", ch2, ch2);
system("PAUSE");
return 0;
}
As the author of the above code have explained:
The program will not work properly because at Line 1, when the user presses Enter, it will leave in the input buffer 2 character: Enter key (ASCII code 13)
and \n (ASCII code 10)
. Therefore, at Line 2, it will read the \n
and will not wait for the user to enter a character.
OK, I got this. But my first question is: Why the second getchar()
(ch2 = getchar();
) does not read the Enter key (13)
, rather than \n
character?
Next, the author proposed 2 ways to solve such probrems:
use fflush()
write a function like this:
void
clear (void)
{
while ( getchar() != '\n' );
}
This code worked actually. But I cannot explain myself how it works? Because in the while statement, we use getchar() != '\n'
, that means read any single character except '\n'
? if so, in the input buffer still remains the '\n'
character?
The program will not work properly because at Line 1, when the user presses Enter, it will leave in the input buffer 2 character: Enter key (ASCII code 13) and \n (ASCII code 10). Therefore, at Line 2, it will read the \n and will not wait for the user to enter a character.
The behavior you see at line 2 is correct, but that's not quite the correct explanation. With text-mode streams, it doesn't matter what line-endings your platform uses (whether carriage return (0x0D) + linefeed (0x0A), a bare CR, or a bare LF). The C runtime library will take care of that for you: your program will see just '\n'
for newlines.
If you typed a character and pressed enter, then that input character would be read by line 1, and then '\n'
would be read by line 2. See I'm using scanf %c
to read a Y/N response, but later input gets skipped. from the comp.lang.c FAQ.
As for the proposed solutions, see (again from the comp.lang.c FAQ):
fflush(stdin)
work? fflush
won't work, what can I use to flush input?which basically state that the only portable approach is to do:
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
Your getchar() != '\n'
loop works because once you call getchar()
, the returned character already has been removed from the input stream.
Also, I feel obligated to discourage you from using scanf
entirely: Why does everyone say not to use scanf
? What should I use instead?