www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/05/30/16:47:10

From: j DOT aldrich6 AT genie DOT com
Message-Id: <199605302018.AA238137504@relay1.geis.com>
Date: Thu, 30 May 96 20:02:00 UTC 0000
To: djgpp AT delorie DOT com
Mime-Version: 1.0
Subject: Re: fflush(stdin) : does it wo

Reply to message 5829559    from DMICOLET AT U-BO on 05/29/96 11:09AM


>I used to get a string with the following :
>
>{
>char One_String[80];
>....
>scanf("%[^\n]",One_String);fflush(stdin);
>....
>}

First, this is a VERY bad way to get a string.  A mechanism for doing
EXACTLY what you are trying so painfully to do already exists within
ANSI C - it's called gets().  Just replace that ridiculous code with:

gets( One_String );

This has the advantage of not only ignoring whitespace, but also
capturing the newline as well.

Another VERY UNSAFE thing you are doing is declaring One_String
to hold a mere 80 characters.  Even under DOS, input lines can be a
lot longer than 80 characters!  If this were to occur when somebody was
using your program, the best you could hope for is it crashing messily.
I recommend in such situations using fgets() instead of gets(), because
fgets() allows you to specify the maximum number of characters read:

fgets( One_String, 80, stdin );

There are two things you have to keep in mind with this method, however.
First, fgets doesn't strip the newline from the end of the string (you have to
do this yourself), and second, if it does reach 80 characters without hitting
a newline, it leaves the remainder of the input line in the buffer, leaving
you to detect and clean up this situation yourself.

Hint:  check to see if the string read contains a newline.  If it DOESN'T,
do another fgets() to clear to the newline, or a simple while loop like so:

while( getchar() != '\n' );

For safety's sake, you may also wish to check for encountering an EOF,
but this is child's play.

>The fflush(stdin) is there to trash the new line, else the next scanf of a
>string does not works.
>This works fine with many compilers (RS6000, SUN, DEC, PC)

And is a legacy of programmers trying to find 'cheats' to work around
some of the limitations of the ANSI spec.  fflush() is NOT designed to
work with input streams, and in fact should never be used with them
period.  Even if it were to perform as you seem to desire it to, I shudder
to think what it would do if the program's standard input were to be
redirected, for example:

foo <input.txt

Logically, if calling fflush() were to clear the entire input buffer, doing it
in this situation would completely wipe out the remaining unread portion
of input.txt.  Even if it does only clear up to the next newline, it is still a
dangerously unpredictable behavior.  Using gets() for all your input
and trapping for input that consists solely of blanks should completely
solve any user interface problems.

>It looks like it does not work with DJGPP V2;
>Another try shows me that the stdin is not emptied (spelling ?) at all.
>
>Is this a known behavior of fflush ?  I am a new user of djgpp (an a old one
>of C) and do not find anything aout that in the FAQ or the info.

DJGPP tends to behave much more sensibly with regards to ANSI
compliance than many other compilers.  It eliminates many of the
potentially fatal crutches that they have created to pander to novice
programmers (not to mention idiotic programming instructors), such
as the above.  Other items worthy of mention are 'flushall()' and
'closeall()', which fit into the same mentality.

BTW, I have looked at the docs for fflush, and they specifically
state that it is used only to write out any buffered data to a file.
Nowhere does it mention anything about clearing an input stream!
This seems very clear to me.

John

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019