[comp.lang.c] how do I clear stdin buffer

tms@cup.portal.com (Taos Mountain Software) (06/15/91)

The stdio function "scanf" works great for input from datafiles, but I always
run into problems when doing interactive tty I/O on Unix systems.

For example, this simple program will go into an infinite loop
if the entry is a non-digit for example ("abc").

	main ()
	{
		int x,stat;;
		do {
			stat=scanf("%d",&x);
		} while (stat != 1);
		...
		...
	}
I know there are plenty of workarounds, but what I'm interested in is a
function like fflush that deals with input streams.

Thanks in advance

Ric Urrutia
tms@cup.portal.com

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/18/91)

In article <43310@cup.portal.com>, tms@cup.portal.com (Taos Mountain Software) writes:

> The stdio function "scanf" works great for input from datafiles, but
> I always run into problems when doing interactive tty I/O on Unix
> systems.

> For example, this simple program will go into an infinite loop if the
> entry is a non-digit for example ("abc").

[compressed, and unimportant stuff deleted -dM]
> 		do { stat=scanf("%d",&x); } while (stat != 1);

It will do the same thing when reading from a data file, too.  This is
not a bug; this is how scanf is supposed to work.

You generally don't want to use scanf for reading interactive input.
(You generally don't want to use it for reading files, either, except
for throwaway programs that you're certain will remain throwaway.)  You
probably should read a full line with fgets and then pick it apart with
sscanf, a character-based scanner, or something like my (unfortunately
not widespread) fopenstr....

> I know there are plenty of workarounds, but what I'm interested in is
> a function like fflush that deals with input streams.

What do you propose it do?  The best direct analogy to fflush that I
can think of is to have it read repeatedly until the stdio buffer is
filled (or EOF or an error occurs).  But since I can't see how that
would help you the slightest in this situation, you must want something
else.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

torek@elf.ee.lbl.gov (Chris Torek) (06/18/91)

In article <43310@cup.portal.com> tms@cup.portal.com
(Taos Mountain Software) writes:
>The stdio function "scanf" works great for input from datafiles, but I
>always run into problems when doing interactive tty I/O on Unix systems.

Avoid scanf.  sscanf() is OK; scanf() is not.  There may be exceptions
to this rule, but I have found none yet.

>... what I'm interested in is a function like fflush that deals with
>input streams.

POSIX says that fflush wipes out pending input.  4.4BSD will probably
have fpurge().  Neither is portable to all ANSI C systems.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

bxw@ccadfa.adfa.oz.au (Brad Willcott) (06/18/91)

tms@cup.portal.com (Taos Mountain Software) writes:

>The stdio function "scanf" works great for input from datafiles, but I always
>run into problems when doing interactive tty I/O on Unix systems.

>For example, this simple program will go into an infinite loop
>if the entry is a non-digit for example ("abc").


#define INT_SIZE 5

>	main ()
>	{
>		int x,stat;
		char buffer[INT_SIZE];

		fflush (stdin);

>		do {
			fgets (buffer, INT_SIZE, stdin);
			stat = sscanf ("%d", &x);
>			/* stat=scanf("%d",&x); */
>		} while (stat != 1);
>		...
>		...
>	}

	fflush (FILE *stream)
	{
		int i;

		while ((i = getc (stream)) != EOF) ;
	}


>I know there are plenty of workarounds, but what I'm interested in is a
>function like fflush that deals with input streams.

-- 
Brad Willcott,                          ACSnet:     bxw@ccadfa.cc.adfa.oz
Computing Services,                     Internet:   bxw@ccadfa.cc.adfa.oz.au
Australian Defence Force Academy,       UUCP:!uunet!munnari.oz.au!ccadfa.oz!bxw
Northcott Dr. Campbell ACT Australia 2600  +61 6 268 8584  +61 6 268 8150 (Fax)

scs@adam.mit.edu (Steve Summit) (06/19/91)

In article <2438@ccadfa.adfa.oz.au> bxw@ccadfa.adfa.oz.au (Brad Willcott) writes:
>	fflush (FILE *stream)
>	{
>		int i;
>
>		while ((i = getc (stream)) != EOF) ;
>	}

1. One should not casually try (and ANSI prohibits) reimplementing
   routines with names reserved to the standard library, such as
   fflush.

2. When (illegally, but if you really know what you're doing)
   reimplementing standard routines, one should really attempt
   to preserve their existing semantics.  (Consider what would
   happen if, elsewhere in the calling program, a call to
   fflush(stdout) were to encounter the reimplementation above.)

3. What the original problem statement required (not that it was
   really well defined or even portably possible) was a way to
   discard typed but unread data (presuming interactive input),
   not everything up to an EOF (i.e. the rest of the "file").

                                            Steve Summit
                                            scs@adam.mit.edu