I figured I could use scanf more safely if I checked its ...

Q

I figured I could use scanf more safely if I checked its return value to make sure that the user typed the numeric values I expect:
int n;

while(1) {
printf("enter a number: ");
if(scanf("%d", &n) == 1)
break;
printf("try again: ");
}

printf("you typed %d\n", n);

but sometimes it seems to go into an infinite loop. Why?

✍: Guest

A

When scanf is attempting to convert numbers, any non-numeric characters it encounters terminate the conversion and are left on the input stream. Therefore, unless some other steps are taken, unexpected non-numeric input ``jams'' scanf again and again: scanf never gets past the bad character(s) to encounter later, valid data. If the user types a character like `x' in response to the code above, the code will loop printing ``try again'' forever, but it won't give the user a chance to try.
You may be wondering why scanf leaves unmatchable characters on the input stream. Suppose you had a compact data file containing lines consisting of a number and an alphabetic code string, without intervening whitespace, like
123CODE
You might want to parse this data file with scanf, using the format string "%d%s". But if the %d conversion did not leave the unmatched character on the input stream, %s would incorrectly read "ODE" instead of "CODE". (The problem is a standard one in lexical analysis: when scanning an arbitrary-length numeric constant or alphanumeric identifier, you never know where it ends until you've read ``too far.'' This is one reason that ungetc exists.)

2015-10-19, 694👍, 0💬