Reputation: 13
I have read so many questions about getchar()
and its behaviour, but still I don't understand this simple code..
while (scanf("%d", &z) != 1)
{
while (getchar() != '\n');
printf ("Try again: ");}
This code is to validate for characters.. From what I infer from this code is that if I input
Stackoverflow
Then the whole line is pushed to the buffer with the newline '\n' also..
Then the getchar()
reads each character from the buffer and returns an integer, cleaning the buffer.. In this case the while loop should loop 12 times (number of characters in Stackoverflow) until it reaches the '\n' character.. but actually it just loops once and the output is
Try again:
means its out of loop and asking for scanf
again.. It goes against my understanding of looping.. Maybe I misunderstood looping.. One additional question,, if getchar()
returns integers then how it could be compared to characters like '\n'?
Upvotes: 1
Views: 322
Reputation: 4708
Reformatting the code to assist with my explanation:
while (scanf("%d", &z) < 1) {
int c; // for getchar()'s return value
while ((c = getchar()) != EOF && c != '\n')
;
printf ("Try again: ");
}
Note that scanf
returns the number of items it read successfully. (I changed the outer while
condition.)
Edit: It is very important that getchar()
be checked for EOF. The loop could spin forever otherwise.
The inner while
is followed by a semicolon. This means it does not have a loop body, i.e. does nothing except evaluate its condition until said condition is false.
Say I type in Stackoverflow
. scanf
sees %d
in its format string, looks for an integer (any number of digits, optionally prefixed by a sign), finds nothing of the sort, and returns failure (i.e. 0
) without changing z
.
Execution enters the loop, where getchar
is called repeatedly until it finds a newline; this reads and discards all erroneous input. The program prints Try again:
(no newline), and the outer loop then evaluates its condition again, trying to read an integer.
Rinse and repeat until an integer is entered, at which point scanf
stuffs it in z
and the loop finishes.
getchar()
(int) to '\n'
(In C, char
is just a smaller int
. C does not have a concept of characters separate from a concept of the integers that represent them.'\n'
is an int
, not a char
, so no problems here. (It's for historical reasons - something to do with K&R C.)
Upvotes: 5