Flush stdin?

J

Jonathan Neill

I'm aware that there is no ANSI (or POSIX, or any standard, to my knowledge)
way of flushing stdin or any other application-level input buffer, but if
anyone knows a hack or a non-portable way to do this, no matter how obscure
or arcane, I'd appreciate it.
 
T

Tom Zych

Jonathan said:
I'm aware that there is no ANSI (or POSIX, or any standard, to my knowledge)
way of flushing stdin or any other application-level input buffer, but if
anyone knows a hack or a non-portable way to do this, no matter how obscure
or arcane, I'd appreciate it.

Um...what does it mean, to flush an input buffer?

If you mean you want to read and discard whatever's in the buffer at
a certain time, under POSIX I suppose you could use non-blocking
reads until they come up empty. I don't think standard C has
non-blocking I/O, does it?

If you mean you want to wipe the buffer's memory space, because the
user entered a password or something, I'd avoid using stdin for such
purposes.
 
A

August Derleth

I'm aware that there is no ANSI (or POSIX, or any standard, to my
knowledge) way of flushing stdin or any other application-level input
buffer, but if anyone knows a hack or a non-portable way to do this, no
matter how obscure or arcane, I'd appreciate it.

You'd do better asking on a system-specific newsgroup. The geeks there
will know a dozen ways to do this on your specific system (or will know if
it can't be done at all). Here, we deal with Standard C, not any system-
specific extensions to the language. If you have a question about ANSI/ISO
C (up to and including C99, and even including pre-Standard K&R C if you
still need it), this is the best place to ask it. If you want to do
something that is system-specific, ask on a system-specific newsgroup for
the best answers.

http://www.eskimo.com/~scs/C-faq/s19.html -- A list of answers to
questions that can't be answered in Standard C. Read the (rest of the) FAQ
for more info.
 
R

Richard Heathfield

Jonathan said:
I'm aware that there is no ANSI (or POSIX, or any standard, to my
knowledge) way of flushing stdin or any other application-level input
buffer, but if anyone knows a hack or a non-portable way to do this, no
matter how obscure or arcane, I'd appreciate it.

What do you mean by "flush"? If you mean that you want to discard the
current character and all subsequent characters until exactly one \n has
been discarded (and this is typically what most people want from a
so-called "flush" of stdin), call this function:

#include <stdio.h>

/* constraint: fp must be open for input */
int fpDrain(FILE *fp)
{
int ch = 0;
while((ch = getc(fp)) != EOF && ch != '\n')
{
continue;
}
return EOF == ch;
}
 
S

Stephan Wilms

Hi,

The problem with non portable solutions is that they tend to be highly
system specific. The solution to the problem must be tailored to the
specifics of the systems where it is intended to be used. Since you
did not describe your system / environment we can not give you a
specific working solution.

For instance there are systems where "fflush(stdin);" actually works
and does what you want (e.g. Microsoft Visual C). Another solution
would indeed be to check your system for a non blocking function to
read from a stream or terminal. To add to the already existant obscure
examples: Microsoft C offers a function called "_kbhit()" to check if
there is pending keyboard input available.
 
M

Martin Ambuhl

Jonathan said:
I'm aware that there is no ANSI (or POSIX, or any standard, to my knowledge)
way of flushing stdin or any other application-level input buffer, but if
anyone knows a hack or a non-portable way to do this, no matter how obscure
or arcane, I'd appreciate it.

It doesn't even mean anything. Read the description of the action of
fflush() on output streams and try to come up with a reasonable analogy for
input streams.
 
A

Alex Vinokur

Jonathan Neill said:
I'm aware that there is no ANSI (or POSIX, or any standard, to my knowledge)
way of flushing stdin or any other application-level input buffer, but if
anyone knows a hack or a non-portable way to do this, no matter how obscure
or arcane, I'd appreciate it.
Look at :
http://groups.google.com/[email protected]
http://alexvn.freeservers.com/s1/download.html (Flushing non-read input data with using tcflush)


=====================================
Alex Vinokur
mailto:[email protected]
http://mathforum.org/library/view/10978.html
=====================================
 
T

Tom Zych

Stephan said:
The problem with non portable solutions is that they tend to be highly
system specific.

<captious>

Really? Gosh. I guess that's why they're non-portable, then?

</captious>
 
T

The Real OS/2 Guy

I'm aware that there is no ANSI (or POSIX, or any standard, to my knowledge)
way of flushing stdin or any other application-level input buffer, but if
anyone knows a hack or a non-portable way to do this, no matter how obscure
or arcane, I'd appreciate it.

100% ANSI compatible:

/* flush stdin */
/* params: */
/* int c int to hold temorary readed char from stdin */
/* */
/* read from stdin until end of file or end of line reached */
#define FLUSHIN(c) while ((c = getc() != EOF && c != '\n')

stdin is commonly line buffered or unbuffered. In both cases reading
until '\n' is dedected is flushing the input stream. Even when stdin
is set to be block buffered (e.g. as pipe or file it makes sense to
"flush". Because stdin is a text stram, so reading until '\n'
syncronises the stream so that the next coming char will be the first
of a line.
 
I

Irrwahn Grausewitz

The Real OS/2 Guy said:
/* flush stdin */
/* params: */
/* int c int to hold temorary readed char from stdin */
/* */
/* read from stdin until end of file or end of line reached */
#define FLUSHIN(c) while ((c = getc() != EOF && c != '\n')
^
There's a ')' missing here. :)
 
K

Kelsey Bjarnason

[snips]

Um...what does it mean, to flush an input buffer?

You're sitting at the keyboard, firing in commands to do this, that, the
other thing. In the process, you inadvertently enter some option which
is potentially dangerous... but you're still merrily typing away, while
the potentially dangerous program is figuring out what to do - you're
queuing up your inputs.

The program, realizing that what you asked for is dangerous, puts up a
prompt "Do you really mean this? y/N" and waits for input. However, since
you've already queued up inputs, it may well see an N (or worse, a Y)
and the results range from annoying to disastrous.

'Course, if the program had flushed input, your queued commands would be
lost... but you wouldn't be feeding an unwanted input into the program at
a critical juncture.

In a GUI system, generally, this would be done with a messagebox and your
typing wouldn't make an iota of difference; in a CLI environment, however,
it can matter.

One frequent solution is to flush input; whether that means reading and
discarding inputs until a strictly valid one is obtained (i.e. fgets and
only accepting a 'Y' or an 'N' by itself, ignoring other typed inputs) or
using some other means, the result is the same: attempting to flush the
input buffer.
 
I

Irrwahn Grausewitz

Kelsey Bjarnason said:
[snips]

Um...what does it mean, to flush an input buffer?

You're sitting at the keyboard, ...
<SNIP>

I am pretty sure he already knows what (usually) is meant when
people talk about "flushing an input buffer": it is the wrong
term for "draining an input buffer".

Irrwahn.
 
T

Tom Zych

Kelsey said:
The program, realizing that what you asked for is dangerous, puts up a
prompt "Do you really mean this? y/N" and waits for input. However, since
you've already queued up inputs, it may well see an N (or worse, a Y)
and the results range from annoying to disastrous.

One frequent solution is to flush input; whether that means reading and
discarding inputs until a strictly valid one is obtained (i.e. fgets and
only accepting a 'Y' or an 'N' by itself, ignoring other typed inputs) or
using some other means, the result is the same: attempting to flush the
input buffer.

Ah, yes. I've noticed that problem and some programs that cope with
it. Never thought of it as "flushing" since that has an entirely
different meaning for output. I think Irrwahn's "draining", or
perhaps "clearing", would be better.

I don't see a good way to do it without non-blocking reads. With
them, of course, it's easy.
 
T

Tom Zych

The said:
stdin is commonly line buffered or unbuffered. In both cases reading
until '\n' is dedected is flushing the input stream. Even when stdin
is set to be block buffered (e.g. as pipe or file it makes sense to
"flush". Because stdin is a text stram, so reading until '\n'
syncronises the stream so that the next coming char will be the first
of a line.

If that's the behavior you want, ok. But another poster pointed out
that one use is to clear the buffer of *all* input, for example, if
the program is asking if you want to do something dangerous. You
wouldn't want it to accept the first character that happens to be in
the input stream in that case.
 
J

Joe Wright

Tom said:
If that's the behavior you want, ok. But another poster pointed out
that one use is to clear the buffer of *all* input, for example, if
the program is asking if you want to do something dangerous. You
wouldn't want it to accept the first character that happens to be in
the input stream in that case.
Don't take this personally, but the point of having an input stream is
to be able to 'read' it. Do that! Determine whether what you read was
dangerous or useful and do the 'wright' thing. It is your program after
all that allows input in the first place. The very least you can do is
'listen' to your user. Having read the input it is always within your
power to ignore it. I see no case for fflush(stdin) or similar.
 
T

Tom Zych

Joe said:
Tom Zych wrote:
Don't take this personally, but the point of having an input stream is
to be able to 'read' it. Do that! Determine whether what you read was
dangerous or useful and do the 'wright' thing. It is your program after
all that allows input in the first place. The very least you can do is
'listen' to your user. Having read the input it is always within your
power to ignore it. I see no case for fflush(stdin) or similar.

I'm not sure you understood me. Did you read Kelsey Bjarnason's
posting?
 
T

The Real OS/2 Guy

Don't take this personally, but the point of having an input stream is
to be able to 'read' it. Do that! Determine whether what you read was
dangerous or useful and do the 'wright' thing. It is your program after
all that allows input in the first place. The very least you can do is
'listen' to your user. Having read the input it is always within your
power to ignore it. I see no case for fflush(stdin) or similar.

You gave the wrong answer.

#define EPMPTYIN while (getc() != EOF) ;

will flush the whole stream. If the stream is not a file it will wait
until the user closes it (e.g. Ctrl. C or CTRL D). If it is a file it
would be readed completely.

But in both cases it would be more easy simply to fclose() it.

Flushing an inputstream is commonly used to syncronise the stream to a
point a logical record/field starts. As it is mostenly impossible to
find the next logical field after something wrong comes in it is more
secure to syncronise to the begin of the next record. So reading
anything until '\n' occures means that one has a clean start point
again.

When your stream has another char's words that defined as syncronison
point you may extend the FLUSHIN macro to find them. But as this
exeeds the work
 
C

Chris Torek

The word "flush" comes from the Middle English "flusshen", meaning
"to take wing" or "to fly up suddenly". (Birds do this in groups
when startled.) This meaning persists today in the phrase "flush
out": things that are hidden can be flushed, chased out of their
concealment for all to see. This is what fflush() does.

Flushing an input buffer, then, would expose its contents to
view -- which is not really all that useful. :)

I suspect what is really wanted is more like a "purge". The BSDs
have an fpurge() function that does this (for both input AND output,
since it has sensible applications in both cases).

You're sitting at the keyboard, firing in commands to do this, that, the
other thing. In the process, you inadvertently enter some option which
is potentially dangerous... but you're still merrily typing away, while
the potentially dangerous program is figuring out what to do - you're
queuing up your inputs.

The program, realizing that what you asked for is dangerous, puts up a
prompt "Do you really mean this? y/N" and waits for input. However, since
you've already queued up inputs, it may well see an N (or worse, a Y)
and the results range from annoying to disastrous.

'Course, if the program had flushed input,

(presumably you mean "purged" input :) -- but we might simply
redefine "flush" to mean "discard", except when it applies to
output, which is not discarded at all...)
your queued commands would be
lost... but you wouldn't be feeding an unwanted input into the program at
a critical juncture.

There is a technical problem here (with a technical but currently
unimplementable solution). Suppose you are sitting at the keyboard
in Australia, typing into the machine located in Vancouver BC, over
a lossy or satellite-based Internet connection with huge latency.
You are "firing in commands" at time T, T+1, T+2, T+3, and so on,
but the transmission to the remote system is rather "lumpy" so that
they arrive there at time T+2, T+6, T+6, T+6, T+9, T+11, T+11, and
so on.

The "dangerous" operation occurs at time T+5 and arrives at the
remote system at time T+9. By then, of course, even more input is
queued at the source (Australia).

Meanwhile, the program prints "do you really mean this" at T+9 and
tries to purge typeahead. The message "do you really mean this"
arrives in Australia at T+11 or so. What input is discarded?

The problem is that the input, output, and flush/purge/whateveryoucallit
operations are not synchronized -- and without some sort of embedded
timing information (or external protocol), they cannot even *be*
synchronized. So fpurge(), while useful, is still quite limited.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top