You are here:

C++/check status without reading from input stream

Advertisement


Question
Hello,
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
}

or

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

or
  if ((cin.rdstate() & ifstream::eofbit))
or
   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

Linh

Answer
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.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.