You are here:

C++/check status without reading from input stream


I am writing some code in the scenario which can be described as follow:
+ program A which writes to standard output (e.g. cout >> whatever).
+ program B which has GUI and also listens to the standart input regularly (using a timer) if there is no input, it returns to the GUI and does something else.

What I expect is B should work without problem in both cases:
(1) user@host $ A | B
(2) user@host $ B

In B's code, I tried using: "cin >> var" or "scanf("%d", &var)" to check if there is something from input.

if (cin >> var) {
 // do smt here


if (scanf("%d", &var)) {
 // do smt here

even in case (1), nothing is read. Did I listen to the wrong stream? And it seems to me that cin and scanf wait for something from standard input and if there is nothing, they keep waiting and the program just hangs.

I also tried checking the status of the input stream by:
   if (cin.rdbuf()->in_avail()) // seems always returns zero

  if ((cin.rdstate() & ifstream::eofbit))
   i = cin.peek();
   if (!cin.rdstate()) {

but nothing worked!

Could you please figure out why or tell me what people do to make it work (in both cases)? Thank you very much


Your problem is that C++ streams and streambufs are synchronous, that is they block until done. If you ask for a character to be read then the program will block until a character is read or there is an error.

So your program will block until there is enough input to fulfil an input request (or there is an error). More characters may be read into the streambuf than are consumed, in which case the is_avail value may be non-zero. However you have to wait until something is read initially. An input streambuf does not get filled auto-magically behind the scenes. It will only be filled via a call to some input request.

C++ has no notion of additional requirements such as reactive GUI message/event processing loops, hence it has no built in support for working with such systems. In fact you sometimes find that you have to use special GUI versions of system API functions (let alone language library operations) for various things just so the GUI processing gets a look in, usually in cases where the OS and GUI are separate systems.

As far as I can see you have several alternatives. Here are a few that spring to mind as possibilities:

1/ Do not use C++ IOStreams, especially for input. You may need to dig down into the way your OS handles stdin with keyboard, files and command line pipes and handle it manually so you can perform the OS equivalent of in_avail type queries.

2/ Use separate threads to handle GUI event/message processing and the input from stdin/std::cin.

3/ Write a streambuf class that handles the integration of GUI event processing while waiting for input, a way of integrating OS in_avail style functionality with C++ IOStreams.

4/ Write a streambuf class that returns immediately with an error if there are no available characters. Another way of integrating OS in_avail style functionality with C++ IOStreams.

5/ Re-design A and B so that A writes its output to a temporary file and B reads it in small chunks while performing other GUI processing.

As stdin is a bit of a special stream because the input may come from a console, file or pipe I would consider using 2/ as other methods are likely to be quite involved. For example you might need to know what method of input is in use so the correct subset of OS API functions can be used to, for example, query if the keyboard has been hit or there are characters available in a pipe.

Using method 2/ allows you to wait as usual but on a separate thread to the one processing your GUI events. When some input has been read the reading thread could notify the GUI thread of the availability by, for example, posting an event or message to the GUI thread, possibly passing a pointer to the an object containing information about the read data such as quantity and data. The GUI thread would handle it as any other event or message. How exactly such synchronisation is handled depends on the system you are using.  


All Answers

Answers by Expert:

Ask Experts


Ralph McArdell






©2017 All rights reserved.