What's so bad about scanf anyway???

Paul N. Hilfinger hilfingr at rama.cs.cornell.edu
Tue Nov 13 15:27:21 AEST 1990


I have been following this discussion with some interest, but I am
still a little puzzled about a few things.

1. Chris Torek displayed the following code to illustrate why scanf is
"fragile"

>	way_the_first() {
>		int i;
>		while (scanf("%d", &i) != EOF)
>			printf("I got %d.\n", i);
>	}

and said that the foremost problem is that "if the user enters the
word `one' instead of the digit `1', the loop runs forever, because
the letter `o' is not a digit and the scanf LEAVES IT BEHIND in the
input stream."

Can't argue with that, but are we criticizing the best example of the
use of scanf?  What are everyone's comments on the following?

	way_the_first_and_a_half() {
	    for (;;) { /* Please no flaming about how to do infinite loops */
	        int i;
		int r = scanf("%d", &i);
		if (r == EOF) break;
		if (r == 1)
		    printf("I got %d.\n", i);
                else
		    (void) getchar();
	    }
	}

I know of one obvious problem.  For the illegal input `--1', scanf
reads the first `-', finds an error, and then getchar reads and throws
away the second `-'.  This could be corrected by using something more
elaborate than getchar() for error correction.  On the other hand,
let's say that my goal in just to produce code that detects errors and
recovers from them adequately (in particular, without blowing up),
even if its choice of recovery is not always perfect.

2. Several contributors have suggested the use of sscanf after using
fgets.  This has problems, since sscanf won't tell you where in its
input string it stopped reading.  Fortunately, there are strtod,
strtol, etc., but they still leave the problem that the newline
character is not just whitespace when using fgets.  One must make
annoying provisions for ends of lines that are not necessary
when input is treated as a continuous stream of characters.  Do any of
you have nice ways of dealing with these problems? 

Thanks for your help.

Paul Hilfinger



More information about the Comp.lang.c mailing list