🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.c.moderated
8 messages
8 total messages Started by Himanshu Gohel Mon, 15 Apr 1996 04:37
fflush(stdin) - not guaranteed to work?
#2593
Author: Himanshu Gohel
Date: Mon, 15 Apr 1996 04:37
38 lines
2033 bytes
In Paul S. Wang's "Introduction to ANSI C on UNIX" he says that
the fflush() function was "not intended to control input buffering"
on page 266.

My question is, why?  Some of my students have written programs using
fflush(stdin) hoping it would clear away anything that's in the input
buffer before a scanf() statement and apparently it works on some PC
based compilers, but when re-compiled on a UNIX system, it does not
always work.

What is the best way to get rid of the '\n' from the input buffer after
a scanf() statement?  In the same book on page 263 I've seen the following
format used in an fscanf() format specifier:

 %*[\n]

which is explained as follows:

"...and %*[\n] consumes and discards the NEWLINE character at the end of
 an input line."

But I've not had much luck with it when used as follows:

    scanf("%c %*[\n]", &test);

The NEWLINE stays in the buffer and thus interferes with the next scanf()
statement. I am aware, however, of the " "%c" format which discards white
space before a character input, but my question is a more general one to
discard the NEWLINE.

If you do post to the newsgroup, please do send me a copy via e-mail too.
Thanks!

-- 
Himanshu Gohel, gohel@csee.usf.edu	     | You only have to do very few
WEB URL: http://www.csee.usf.edu/~gohel/     | things right in your life as
Geometric Modeling & Graphics Research Group | long as you don't do too many
U of South Florida, Tampa, FL. USA.	     | things wrong - Warren Buffett
Re: fflush(stdin) - not guaranteed to work?
#2595
Author: P.Bennett
Date: Mon, 15 Apr 1996 18:08
24 lines
1734 bytes
In article <4ksjpn$rjt@solutions.solon.com>, gohel@csee.usf.edu writes...
>In Paul S. Wang's "Introduction to ANSI C on UNIX" he says that
>the fflush() function was "not intended to control input buffering"
>on page 266.

I believe the C standard agrees with him.  :-)

>What is the best way to get rid of the '\n' from the input buffer after
>a scanf() statement?  In the same book on page 263 I've seen the following
>format used in an fscanf() format specifier:

don't use scanf() for direct user input - besides the "leftover '\n'" problem,
it can cause great grief if the user enters a letter when scanf() is expecting
a number.

A better input procedure is to get a line with fgets(), then parse it with
sscanf(), strtok(), or other functions.

Peter Bennett VE7CEI                | Vessels shall be deemed to be in sight
Internet: bennett@triumf.ca         | of one another only when one can be
Packet: ve7cei@ve7kit.#vanc.bc.ca   | observed visually from the other
TRIUMF, Vancouver, B.C., Canada     |                          ColRegs 3(k)
GPS and NMEA info and programs: ftp://sundae.triumf.ca/pub/peter/index.html
or: ftp://ftp-i2.informatik.rwth-aachen.de/pub/arnd/GPS/peter/index.html
Re: fflush(stdin) - not guaranteed to work?
#2598
Author: Maurizio Loreti
Date: Mon, 15 Apr 1996 18:09
43 lines
2442 bytes
In article <4ksjpn$rjt@solutions.solon.com>, gohel@csee.usf.edu (Himanshu Gohel) writes:
>In Paul S. Wang's "Introduction to ANSI C on UNIX" he says that
>the fflush() function was "not intended to control input buffering"
>on page 266.
>
>My question is, why?  Some of my students have written programs using
>fflush(stdin) hoping it would clear away anything that's in the input
>buffer before a scanf() statement and apparently it works on some PC
>based compilers, but when re-compiled on a UNIX system, it does not
>always work.

Apparently you missed Q/A 12.26 of the FAQ list,
RTFM.mit.edu:pub/usenet/comp.lang.c/*:

12.26:	How can I flush pending input so that a user's typeahead isn't
	read at the next prompt?  Will fflush(stdin) work?

A:	fflush() is defined only for output streams.  Since its
	definition of "flush" is to complete the writing of buffered
	characters (not to discard them), discarding unread input would
	not be an analogous meaning for fflush on input streams.

	There is no standard way to discard unread characters from a
	stdio input stream, nor would such a way be sufficient unread
	characters can also accumulate in other, OS-level input buffers.

	References: ANSI Sec. 4.9.5.2; ISO Sec. 7.9.5.2; H&S Sec. 15.2.

>What is the best way to get rid of the '\n' from the input buffer after
>a scanf() statement?  In the same book on page 263 I've seen the following
>format used in an fscanf() format specifier:
>
> %*[\n]

The best way is to not use scanf at all :-)

Try fgets to read a whole line, if you want destroy the '\n' (if any!)
with an appropriate statement (the FAQ list in Q/A 7.1 suggests
  if((p = strchr(answer, '\n')) != NULL) *p = '\0';
), then parse appropriately the input line.
--
Maurizio Loreti                       http://mvxpd5.pd.infn.it/wwwcdf/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          loreti@padova.infn.it
Re: fflush(stdin) - not guaranteed to work?
#2599
Author: GHouck
Date: Mon, 15 Apr 1996 18:12
26 lines
1063 bytes
gohel@csee.usf.edu (Himanshu Gohel) wrote:
[snip]
>
>What is the best way to get rid of the '\n' from the input buffer after
>a scanf() statement?  In the same book on page 263 I've seen the following
>format used in an fscanf() format specifier:
>

Himanshu,
I would recommend the following:

  char  *pnl;
  char  inpBuf[MAXBUF];
  FILE  *strm;
  ...
  ...
  while( fgets(inpBuf,sizeof(inpBuf),strm) ) {
    ...
    if( (pnl=strchr(inpBuf,'\n')) )  /* truncate the newline */
      *pnl = '\000';
    ...
    sscanf( inpBuf,... );
    ...
  }

Yours, Geoff Houck
Re: fflush(stdin) - not guaranteed to work?
#2600
Author: Kazimir Kylheku
Date: Mon, 15 Apr 1996 18:12
64 lines
3054 bytes
In article <4ksjpn$rjt@solutions.solon.com>,
Himanshu Gohel <gohel@csee.usf.edu> wrote:
>In Paul S. Wang's "Introduction to ANSI C on UNIX" he says that
>the fflush() function was "not intended to control input buffering"
>on page 266.
>
>My question is, why?  Some of my students have written programs using
>fflush(stdin) hoping it would clear away anything that's in the input
>buffer before a scanf() statement and apparently it works on some PC
>based compilers, but when re-compiled on a UNIX system, it does not
>always work.

There is a detailed discussion in the comp.lang.c FAQ that covers VMS, UNIX and
DOS in this respect, as far as I recall. It may be downloaded via FTP
from rtfm.mit.edu/put/usenet

Questions about keyboard buffers are very frequent on this newsgroup.

The C language has no concept of a keyboard buffer. The standard IO library
functions have their own buffers. But these are different entities from
hardware keyboard buffers, or buffers internal to the operating system. The
contents of the latter two are inaccessible from the C language.

There may be any number of keystrokes buffered in the OS, or hardware---your
program cannot know this without talking to special drivers or taking other
such similar platform-specific measures that are outside of the scope of C.

>What is the best way to get rid of the '\n' from the input buffer after
>a scanf() statement?  In the same book on page 263 I've seen the following
>format used in an fscanf() format specifier:
>
> %*[\n]
>
>which is explained as follows:
>
>"...and %*[\n] consumes and discards the NEWLINE character at the end of
> an input line."
>
>But I've not had much luck with it when used as follows:
>
>    scanf("%c %*[\n]", &test);

That's because your book is wrong. Which one is it?


You want to match characters that are _not_ equal to a newline:

     scanf("%c %*[^\n]", &test);


The K&R2 book explains this on page 246:

	[...] matches the longest non-empty string of input characters
	      from the set between brackets.

Thus [^\n] means match the longest non-empty string of all input characters
other than a newline.

The newline is then consumed because it is whitespace, and scanf() naturally
thrives on vegetation consisting of spaces, tabs and newlines.

You and your students ought to be using a solid reference like the Kernighan
and Ritchie, or the Harbison and Steele book. Your department can surely afford
a copy of the ISO/IEC standard as well, for reference purposes, no?
Re: fflush(stdin) - not guaranteed to work?
#2603
Author: News User Id
Date: Wed, 17 Apr 1996 01:44
26 lines
1775 bytes
In article <4ku3id$53h@solutions.solon.com>, c2a192@ugrad.cs.ubc.ca
(Kazimir Kylheku) writes:
> In article <4ksjpn$rjt@solutions.solon.com>,
> Himanshu Gohel <gohel@csee.usf.edu> wrote:
>> My question is, why?  Some of my students have written programs using
>> fflush(stdin) hoping it would clear away anything that's in the input
>> buffer before a scanf() statement and apparently it works on some PC
>> based compilers, but when re-compiled on a UNIX system, it does not
>> always work.
> 
> There is a detailed discussion in the comp.lang.c FAQ that
> covers VMS, UNIX and DOS in this respect, as far as I recall.

Before anyone goes off and looks and is disappointed (actually,
it's probably too late for that), the only system-specific
question that the comp.lang.c FAQ list answers in that much
detail is, "How do I read one character without waiting for
the RETURN key?".  To the implicit followon question, "If
fflush(stdin) won't work, how *can* I flush the user's typeahead
before issuing a prompt confirming whether I should reformat the
hard drive?", the FAQ list suggests no answer, because I don't
know a good one (other than, your program probably shouldn't be
offering to do that at all).

					Steve Summit
					scs@eskimo.com
Re: fflush(stdin) - not guaranteed to work?
#2607
Author: The Amorphous Mass
Date: Wed, 17 Apr 1996 15:44
29 lines
1873 bytes
On 16 Apr 1996, News User Id wrote:
> To the implicit followon question, "If
> fflush(stdin) won't work, how *can* I flush the user's typeahead
> before issuing a prompt confirming whether I should reformat the
> hard drive?", the FAQ list suggests no answer, because I don't
> know a good one (other than, your program probably shouldn't be
> offering to do that at all).

  Since you offer answers to questions that might work on most 
implementations (eg the definition of the offsetof() macro) you might 
suggest a variation on

void Flush()
{
    while(getchar() != '\n')
        ;
}

  which is only called if the last character read was not a newline.  
This has yet to fail on the systems I've tested it on, but that obviously 
doesn't mean that it always works.  Can anyone get it to fail to 
transparently clear stdin (by, say, requuiring that the user hit <CR>)?  
Remember to only call it if the last character read was not a newline. :-)

--
James Robinson            "Because we are returning a copy for postfix ++ 
james-robinson@uiowa.edu  expressions, statements such as (c++)++; won't
robinson@cs.uiowa.edu     work as expected."            -- Weiskamp & Flamig,
                                           _The_Complete_C++_Primer_, 2nd ed.
Re: fflush(stdin) - not guaranteed to work?
#2612
Author: Kazimir Kylheku
Date: Wed, 17 Apr 1996 15:45
19 lines
1596 bytes
In article <4l1idn$pvs@solutions.solon.com>,
News User Id  <news@eskimo.com> wrote:
 >Before anyone goes off and looks and is disappointed (actually,
 >it's probably too late for that), the only system-specific
 >question that the comp.lang.c FAQ list answers in that much
 >detail is, "How do I read one character without waiting for
 >the RETURN key?".  To the implicit followon question, "If
 >fflush(stdin) won't work, how *can* I flush the user's typeahead
 >before issuing a prompt confirming whether I should reformat the
 >hard drive?", the FAQ list suggests no answer, because I don't
 >know a good one (other than, your program probably shouldn't be
 >offering to do that at all).

Ah, right. My apologies. I was thinking along the lines that these two problems
are so closely related that the answer to one is really tied to the other.
Though it doesn't have a ``canned'' answer for various platforms, the FAQ does
give some leads in the right direction.
-- 
I'm not really a jerk, but I play one on Usenet.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads