What's so bad about scanf anyway???

Chris Torek chris at mimsy.umd.edu
Mon Nov 12 18:04:41 AEST 1990


Whenever you deal with (significant pause, change of voice tone) users
(shudder) ( :-) ) you must think of all the things that could possibly
go wrong.  It is impossible to make any system completely foolproof---
fools are too ingenious---but it is usually not too hard to make a system
fool-resistant.

Consider the following three ways to read and print a series of integers:

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

	way_the_second() {
		int i;
		char inbuf[10];
		while (gets(inbuf))
			printf("I got %d.\n", atoi(inbuf));
	}

	way_the_third() {
		int i;
		char inbuf[10];
		while (fgets(inbuf, sizeof inbuf, stdin))
			printf("I got %d.\n", atoi(inbuf));
	}

The first is susceptible to a number of problems.  Foremost, however,
is the user typing the wrong thing.  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.
Each call to scanf() finds another `o' and then puts it back.

The second is susceptible to a different kind of problem.  If a user
types in `supercalifragilisticexpialidocious', your program does something
completely unpredictable, because you have asked the computer to shove
35 characters (34 plus '\0') into a 10 character buffer.  It Just Ain't
Gonna Work.

The third, while imperfect, is the best of the three.  There is nothing
the user can type in (other than special system functions that, say,
trap into a debugger) that will cause the program to run wild.

This is why we (`we' == comp.lang.c posters who have seen it before)
recommend using fgets to read input.  Scanf and gets are both rather
fragile; fgets is not.  (Once you have some input, you can pick it
apart however you like, including via sscanf.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list