prev up next   top/contents search

comp.lang.c FAQ list · Question 12.19

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. [footnote] Why?


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

See also question 12.20.

References: ISO Sec. 7.9.6.2
H&S Sec. 15.8 pp. 357-64


prev up next   contents search
about this FAQ list   about eskimo   search   feedback   copyright

Hosted by Eskimo North