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?
Author: Himanshu Gohel
Date: Mon, 15 Apr 1996 04:37
Date: Mon, 15 Apr 1996 04:37
38 lines
2033 bytes
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?
Author: P.Bennett
Date: Mon, 15 Apr 1996 18:08
Date: Mon, 15 Apr 1996 18:08
24 lines
1734 bytes
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?
Author: Maurizio Loreti
Date: Mon, 15 Apr 1996 18:09
Date: Mon, 15 Apr 1996 18:09
43 lines
2442 bytes
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?
Author: GHouck
Date: Mon, 15 Apr 1996 18:12
Date: Mon, 15 Apr 1996 18:12
26 lines
1063 bytes
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?
Author: Kazimir Kylheku
Date: Mon, 15 Apr 1996 18:12
Date: Mon, 15 Apr 1996 18:12
64 lines
3054 bytes
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?
Author: News User Id
Date: Wed, 17 Apr 1996 01:44
Date: Wed, 17 Apr 1996 01:44
26 lines
1775 bytes
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?
Author: The Amorphous Mass
Date: Wed, 17 Apr 1996 15:44
Date: Wed, 17 Apr 1996 15:44
29 lines
1873 bytes
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?
Author: Kazimir Kylheku
Date: Wed, 17 Apr 1996 15:45
Date: Wed, 17 Apr 1996 15:45
19 lines
1596 bytes
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