Re: Using std::cin.rdbuf()->in_avail()
Paul wrote:
I have a small command-line (console) application which, I thought, it
would be good to allow users to pause and to resume - or exit.
That's what signals or flow control are for... though I'm not sure they work
sufficiently under win32.
std::cout << "Enter choice: 'P' - pause, 'Q' - quit: ";
char ch;
while (!finish) {
if (std::cin.rdbuf()->in_avail()) {
1. in_avail() does not guarantee that no characters are available when it
doesn't say that any are available. Only if it says there are some there
are some.
2. It is a function of the streambuffer, which is more low-level than the
stream itself - we will come to the meaning of that soon.
if (std::cin >> ch) {
Okay, unless you explicitly excluded that, this function will read the first
non-whitespace (!!) character into 'ch'. If there is only whitespace,
in_avail() will happily say there is input while this here will block.
std::cin.sync(); // flush remaining characters
No, that's not what this does, use ignore().
the code worked fine with the sole exception that if the user did not
press anything and let the applicaiton run to the end, on its termination
he would still have to press something, since "std::cin >> ch" would
block. This was the problem I tried to avoid by using
std::cin.rdbuf()->in_avail(); however, the code as written does not take
any input until after the thread exits when this becomes useless. Is there
a way to cause, say, some termination code in the thread doing processing
to unblock std::cin when it is no longer needed or is there perhaps a
better way to use .in_avail()?
A raw way would be to simply exit() from the thread, taking the whole
program with it.
Other than that, you will have to revert to low-level keyboard handling
routines, C++ IOStreams simply don't work like that. The first approach is
to poll getch() and the flag that signals the termination of the worker
thread. A more elaborate approach would be to use select().
Uli