1

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'?

1 Answer 1

5

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.

But what does the code do?

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.

And what about comparing getchar() (int) to '\n' (char int)?

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.)

Sign up to request clarification or add additional context in comments.

4 Comments

With a loop to read to newline, you need to consider the possibility of getting EOF too — because your loop will run a long time if it comes acrosss EOF before coming across a newline. You should use: int c; while ((c = getchar()) != EOF && c != '\n') ; (where the last semicolon would be on a line on its own, but you can't show that in a comment). You can test for newline before EOF if you prefer; you do need to check both, though. And remember that getchar() returns an int, not a char.
@JonathanLeffler Thanks. I'll edit the EOF thing in. (I know that stuff. I swear. I just forgot.)
Thanks.. I dont believe i failed to see that semicolon.. Moral, "Dont take C lowly, one semicolon can ruin your weekend".
About your last paragraph, in C, '\n' is an int, not a char. But nice explanation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.