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?
you can try
where %*c accepts and ignores the newline
one more method instead of fflush(stdin) which invokes undefined behaviour you can write
don't forget the semicolon after while loop
A portable way to clear up to the end of a line that you've already tried to read partially is:
This reads and discards characters until it gets
\n
which signals the end of the file. It also checks againstEOF
in case the input stream gets closed before the end of the line. The type ofc
must beint
(or larger) in order to be able to hold the valueEOF
.There is no portable way to find out if there are any more lines after the current line (if there aren't, then
getchar
will block for input).Short, portable and declared in stdio.h
Doesn't get hung in an infinite loop when there is nothing on stdin to flush like the following well know line:
A little expensive so don't use it in a program that needs to repeatedly clear the buffer.
Stole from a coworker :)
The lines:
doesn't read only the characters before the linefeed (
'\n'
). It reads all the characters in the stream (and discards them) up to and including the next linefeed (or EOF is encountered). For the test to be true, it has to read the linefeed first; so when the loop stops, the linefeed was the last character read, but it has been read.As for why it reads a linefeed instead of a carriage return, that's because the system has translated the return to a linefeed. When enter is pressed, that signals the end of the line... but the stream contains a line feed instead since that's the normal end-of-line marker for the system. That might be platform dependent.
Also, using
fflush()
on an input stream doesn't work on all platforms; for example it doesn't generally work on Linux.You can do it (also) this way: