Path: utzoo!utgpu!attcan!uunet!husc6!uwvax!oddjob!ncar!ames!oliveb!sun!thetone!swilson From: swilson%thetone@Sun.COM (Scott Wilson) Newsgroups: comp.sys.mac.programmer Subject: Re: LSC 3.0 scanf deletes Keywords: delete, scanf Message-ID: <62725@sun.uucp> Date: 4 Aug 88 00:58:32 GMT References: <2559@pt.cs.cmu.edu> <587@helios.ee.lbl.gov> <5794@haddock.ISC.COM> Sender: news@sun.uucp Reply-To: swilson@sun.UUCP (Scott Wilson) Organization: Sun Microsystems, Mountain View Lines: 64 scanf is not a useless function! While I believe that to approach 100% bullet-proof i/o you have to do everything yourself one character at a time, scanf is still useful. The problem is that most people don't know how to use scanf. Consider this example: #include main() { int i; do { printf("Enter a number between 1 and 100: "); scanf("%d", &i); } while (i < 1 || i > 100); printf("You typed: %d\n", i); } This is a common problem when using scanf. The user types a letter, scanf pushes it back and the program goes into an infinite loop (assuming the garbage value of an uninitialzed i is out of range). The solution: don't use scanf? Not necessarily. Scanf returns a value to help out in this situation. From the Sun0S 4.0 scanf man page: scanf() returns the number of successfully matched and assigned input items; this number can be zero in the event of an early conflict between an input character and the con- trol string. The constant EOF is returned upon end of input. Note: this is different from 0, which means that no conversion was done; if conversion was intended, it was frustrated by an inappropriate character in the input. Now I know that I have seen some scanfs that return something different like the number of characters read. ANSI should clear this up (using the above I think). My LSC manual is at home so I don't know what that scanf returns. So we change the example to this: #include main() { int i; do { printf("Enter a number between 1 and 100: "); if (scanf("%d", &i) != 1) { while ((i = getchar()) != '\n') /* skip bad stuff */ ; i = 0; /* or something else out of range */ } } while (i < 1 || i > 100); printf("You typed: %d\n", i); } Note that the program does not go into an infinite loop because the offending character that caused scanf not to match a decimal integer has been removed from the input stream. -- Scott Wilson arpa: swilson@sun.com "Why do dogs lick Sun Microsystems uucp: ...!sun!swilson their balls? Because Mt. View, CA they can!"