Clearing keyboard buffer in C++ - c++

I one part of my application I have used Sleep(5000) (I need to wait 5 sec)
The problem is that if the user presses any keyboard key during these 5 seconds, the keys will be read after sleep and it causes problems for my app.
How can I empty the buffer after sleep?
I tried cin.clear() and setbuf(stdin, NULL) but they can't clear the buffer if there is more than one character in the buffer.

The two functions you are using don't have the effect you expect them to have:
clear() doesn't affect the buffer at all but rather clears the error flags. That is, if there was an unsuccessful read a flag is set (std::ios_base::failbit). While any error flag is set (there are a few more), the stream won't attempt to read anything.
setbuf(0, 0) affects the stream's internal buffer to not exist (calls with non-null values have implementation-defined meaning which is typically "do nothing"). This is generally a Bad Idea because it causes the streams to be very slow. Also, the keys pressed by a user are probably not stored in this buffer anyway but rather in the operating systems input buffer until they are sent to application (there are platform specific ways to turn off the operating system input buffer, e.g., on POSIX you'd use tcsetattr() to set the input into non-canonical mode).
In either case, not having a buffer doesn't really help you anyway: The user may very well have typed valid input. The proper approach is to attempt reading the available input and, if this fails, to rid of the offending character (or characters). To this end you'd attempt to read the input and if it fails you'd clear() the stream and ignore() one or more characters (this example ignores an entire line; call ignore() without parameters to just ignore one character):
T value;
while (!(std::cin >> value)) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
You always need to verify that the input was successful anyway and the few extra lines are just adding a bit of recovery code.

The simplest way to clear the keyboard input buffer is
while(kbhit()) getch();
just put that code in your program wherever you want to clear your buffer .
headerfile needed for that is conio.h

This seems to work for Windows 10 compiled with Code::Blocks:
#include <conio.h>
/**
* clears keyboard buffer
*
* #author Shaun B
* #version 0.0.2
* #fixed 15-01-2016
*/
void clearKeyboardBuffer()
{
while (_kbhit())
{
_getche();
}
}
Then called from where is needed in your C++ script.

Related

using c++ input stream cin without blocking

I am trying to use the c++ standard input stream cin to get a user input without blocking the execution of the program. I have this code:
char ch;
int flag=1;
do
{
if(cin.rdbuf()->in_avail())
{
cin.get(ch);
flag=0;
}
else
//do something else
}while(flag);
//do something with the input
The idea here is to wait for user input without blocking while doing something else and as soon as the user provides an input we process the input( all in one thread). I know from the documentation the streambuf class used by the input stream provides the in_avail() function which will return a non-zero values when ever there is input ready in the buffer. The code above is not working as i expected it and is looping forever even if i provide a keyboard input at some point. i am using MS visual studio 2005 in windows 7. what am i missing here?
The function in_avail does:
Returns the number of characters available in the get area.
The get area may be empty even if some characters are readable from the underlying operating system buffer.
You will trigger a refill of the get area when you effectively call a read operation on the streambuf. And that operation will block. The reason is that the method underflow which is responsible for filling the get area:
Ensures that at least one character is available in the input area
And to ensure this, it must block until some character is read.

Clearing eof bit not working with while loop

I have a program I'm trying to write that constantly monitors a log file and outputs specific items into a new file.
I'm using essentially.
for (int i = 1; i < y; i ++)
getline(read, line); // skips to the last known end
while (getline(read, line))
{
cout << line;
}
read.clear();
I also keep track of the line I'm on just using the increment operator on a variable. At the end of the file I clear the eof bit and seek to the last line I was on. From using the debugger it seems that it works. I retrieve the next line in the file as its being written but when I call back to my while (getline(read,line)); it skips going through the while loop, why is that?
program reads the last line in the file.
Sleeps for 5 minutes.
The input file has had new lines added to it from a third party.
After the sleep it wakes up and goes back to the while loop.
It successfully retrieves the new lines from the input. But fails to
enter the while loop again
When using std::getline() at the end of a file both std::iostate::eofbit and std::iostate::failbit are set. In fact, it is std::iostate::failbit which causes the loop to exit. You'll need to clear both of these flags prior to any seek.
For a system which needs to use IOStreams I would actually not bother reading the leading lines but merely wait a bit, clear the flags, and try again. The main issue is detecting whether a complete line is read which could be done by simply reading individual characters, e.g., using std::istreambuf_iterator<char>.
Otherwise I'd look for a system API which provide some sort of indication that new data is available on a file. Older system generally don't provide such facilities but newer system generally have some event-based interface which can be used to get hold of newly available data. The advantage is normally that the processes doesn't poll for new data but idly waits until it gets notified about new data. I haven't used it myself but it seems libuv does this sort of operations in a somewhat platform-independent form.

C++:can the condition state of cin stream be recovered after entering EOF

Here is my code for test:
#include<iostream>
using namespace std;
istream& func(istream &);
int main()
{
if(func(cin))
cout<<"good"<<endl;
return 0;
}
istream& func(istream &is)
{
int num;
is.clear();
auto old_state = is.rdstate();
while(is>>num)
cout<<num<<endl;
is.setstate(old_state);
return is;
}
The problem is:if I enter a char or the mark of EOF(ctr_z in my system) to break the while loop,then the program terminates directly.I was expecting that the cin stream can be reset to a normal state and be returned:
if(func(cin))
cout<<"good"<<endl;
But I can't get that output when program ends.
So what's wrong with my understanding?
You need to ignore the eror and then clear it. So as an example you just need to change your while loop to something like this:
while(true)
{
if(is>>num)
cout<<num<<endl; //if cin is numeric
else // we have an error
{
is.ignore(); // ignore the last error (else your program will run crazy)
is.clear(); // clear the state
break; // terminate console reading
}
}
It's because setstate does not really clear the old flags (read the linked reference to see why)
If you want to completely reset the flags then you need to use the clear function. Not that I really recommend it though, as it gives you a false state of the stream. Instead you should explicitly check the state.
The state can be recovered after an invalid input: failure to parse the input according to the expected type just sets std:: ios_base::failbit which can be clear()ed. Since the character causing the problem is not removed, you'll probably need to get rid of it (e.g. using ignore()) or parae the data differently.
Although EOF is also just a flag (std::ios_base::eofbit) clearing it in general won't recover the from having reached the end of the stream. Specific streams may have a way to carry on reading but the console is likely to be disconnected after an end of stream indicator (e.g., Ctrl-D or Ctrl-Z). Depending on the system it may be possible to create a new connection to the console, e.g., by opening a file stream to /dev/tty.
If you really want to use control characters to indicate special processing you'll need to disable the default processing and manage them within the program. On UNIX systems you'd set the stream into noncanonical mode using tcgetattr() and tcsetattr(). Once this is done all characters entered are seen and can be processed accoringly, probably in a custom stream buffer. I don't know how to do something similar on other systems.

Why does std::cin's extractor operator wait for user input?

I know that this may be a stupid question but I am not sure how getting user input from the terminal actually works.
I understand input/output conceptually and I have no problem using them but I am lost when it comes to how these are actually implemented at a basic level.
As far as I know all stream objects use a type of buffer. If you extract all the characters you reach eof. It's this part I am probably wrong and I would like to know more about. For instance when we use the std::cin's extractor operator, it waits for input. How does it differentiate between waiting for input and reaching eof (nothing else to read) ?
std::cin doesn't do anything special. Like all file input, it
emits a system level read (read in Unix, ReadFile in
Windows), for enough bytes to fill its buffer (usually something
well over 1K today). It is the system which detects that the
input is from a keyboard, and behaves differently: from a file,
the system will read as many bytes as are available, up to the
end of file or the number requested, and return immediately.
From the keyboard, the system will normally read the characters
into an internal buffer until enter, to allow editing (back
space, etc.), and only on enter will it pass this buffer back to
the caller (after having appended the new line marker).
EDIT:
Sort of as a summary as to elements mentionned in the
discussion: I'll take as an example what happens in a Unix
system (but Windows is basically the same, modulo the way it
reports the different information). The istream itself is
buffered. When you try to extract a character (an >>
operator, istream::get, etc.), the stream will return it from
its buffer. If there are no more characters left in the buffer,
it will make a read request to the system, with the address
and the size of its buffer. (On todays systems, I would be
surprised to see a buffer of less than 1K.) What the system
does with it will depend on what the file descriptor designates:
a file
The system will copy bytes from the current position in the
file, until it has filled the buffer or reached end of file. It
returns the number of bytes it copies (or -1, if there is an
error).
a keyboard
For keyboards, the system maintains an internal buffer of
its own, and reads line by line. This buffer will only be
considered "ready" when the user presses enter; before that, the
system will simply not return from the `read`. This allows the
system to implement line editing; e.g. processing things like
a backspace. When you hit enter, the system adds the (system
specific) new line sequence to the buffer, and returns with the
number of characters it has copied into the buffer. (Thus, not
0, since there is the new line.) This procedure can be modified
in two ways: both Unix and Windows have a special characters
(control-D under Unix, control-Z under Windows) which tells the
system to return immediately from the read, with whatever the
buffer contains at the moment. If you're at the start of
a line, the buffer contains nothing, the `read` returns
0 characters read, and the stream treats it as an end of file.
And if the stream buffer size is less than the number of characters in
the line (because you've calmly typed in 100000 characters
without a new line), `read` will return the maximum that will
fit in the buffer, and the next `read` will return immediately
with the rest of the line (or the next n `read` will return
immediately, until the entire line has been read).
a pipe
The system will wait until either there are as many
characters as requested in the pipe, or there are no more
processes left with the pipe open for write. It will then copy
the number of characters requested (or less, of the write side
is closed), and return the number copied.
If the read indicates an error, the stream will set badbit;
if the read returns 0 characters read, the stream will treat
it as end of file.
A std::istream might have a limited amount of data (a file on a hard drive, ...) or an unlimited amount of data (a sensor, ..., interactive user input). In addition there might be a special character representing EOF.
An interactive input from a console/terminal is an infinite input. Unless a special character is entered (Linux: ctl-d), the stream never reaches EOF.
A non interactive input from a pipe will (should/might) end in a EOF.

How to Determine if STDIN is Empty?

I'm writing an emulator for my Operating Systems course. The problem I have is that we need to get all our .job files (they are like application programs being fed to the emulator) from STDIN and read them in.
Call:
./RMMIX < aJob.job
I just slurp it with
while(getline(std::cin, line))
line by line. The problem is, if I do not put anything to STDIN, then cin will wait for user input- NOT what I want. I need the program to recognize a lack of text on STDIN and terminate, not wait for user input instead.
I have determined that I can query the length like so:
size_t beg = std::cin.tellg();
std::cin.seekg(0, std::ios_base::end);
size_t end = std::cin.tellg();
std::cin.seekg(0, std::ios_base::beg);
and terminate if std::cin has a length of 0.
Are there any other solutions to this? Is this a portable solution?
I don't think there's a platform independent way of doing this, but on Unix-based systems you should be able to do:
#include <unistd.h>
...
int main() {
if (!isatty(0)) {
// stdin is being streamed from a file or something else that's not a TTY.
}
...
}
However, I think doing it via a command line option is the preferred approach.
You need to redesign your program. Instead of reading from standard input, read from a named file, who's name you provide on the command line. Then instead of:
./RMMIX < aJob.job
you say:
./RMMIX aJob.job
This is much easier and more portable than trying to determine if there is anything in standard input.
You might also look at this http://www.programmersheaven.com/mb/CandCPP/232821/232821/non-blocking-reads-on-stdin/ for an idea that comes at the problem from another direction -- don't check the number of bytes on the stream, but instead just make the read succeed immediately and then check to see if anything was read.
You can press Ctrl+D on the command line to signal end-of-file for standard input on the running program.
This is desired behavior. Otherwise, if programs exited immediately when no input remained, pipelines could randomly be broken by commands that were waiting on another command that had not been scheduled to run (and that had not produced any additional output), or that buffered output and emitted it all at once, like sort does.
When using io redirection to pull stdin from a file via something like ./RMMIX < file.txt, this end-of-file condition is signaled automatically when there is no more data left in the file. For input read from a terminal, waiting is probably the desired behavior.