Re: is cin always the keyboard's input?

From: tom_usenet (tom_usenet_at_hotmail.com)
Date: 10/15/03


Date: Wed, 15 Oct 2003 18:33:15 +0100

On Wed, 15 Oct 2003 16:18:53 +0300, Bob Smith <bobsmith@jippii.fi>
wrote:

>
>
>stephan beal wrote:
>
>> Bob Smith wrote:
>>
>>
>>>question in subject.
>>>does the standard say anything about this or is it platform dependent?
>>>any advice much appeciated
>>>
>>
>> Indeed, the whole point of 'cin' is to keep this detail hidden from you. It
>> is not only platform-dependent, but case-dependent.
>> e.g., when you do any of the following:
>>
>> cat file | myapp
>> myapp < file
>>
>> these are instructing the system to use the file (more specifically, the
>> input stream) as cin.
>>
>>
>> See section 15.17 in:
>> http://www.parashift.com/c++-faq-lite/input-output.html
>
>
>well here is my problem:
>m_reading is a bool value, qDebug(...) is a qt function, qxevent is a
>class which can red from streams.
><snip>
>
> if ( !m_reading ){
> if ( std::cin.rdbuf()->in_avail() ){

in_avail will generally be 0 if you haven't attempted a read operation
- it usually just returns the number of characters buffered by the
underlying streambuf. You need to
a) Set stdin to non-blocking mode (in an OS specific way)
b) Try reading something from cin to fill the buffer.

> m_reading = true;
> qDebug( "reading...");
> QxEvent e;
> while( cin >> e ) {
> m_event_queue.push( e );
> counter++;
> }

Here the stream will be in an error state (eof). All operations on
such a stream will fail. Add here:

if (cin.eof())
{
  cin.clear();
}
else
{
  //something serious has gone wrong.
  qDebug(strerror(errno)); //or whatever.
  throw something;
}

> qDebug( "...read!");
> m_reading = false;
> }else{
> qDebug("..no data" );
> }
> }else{
> qDebug("already reading, return to caller");
> }
> qDebug("ready");
></snip>
>

Here's my take on the code:

//set stream to non-blocking

if ( !m_reading ){
     m_reading = true;
     qDebug( "reading...");
     QxEvent e;
     while( cin >> e ) {
       m_event_queue.push( e );
       counter++;
     }
     if (cin.eof())
     {
       cin.clear(); //clear error state
     }
     else
     {
       throw serious_error();
     }
     qDebug( "...read!");
     m_reading = false;
}else{
    qDebug("already reading, return to caller");
}
qDebug("ready");

Alternatively, just set the stream to blocking so that process b waits
for data. You could always put the busy wait in its own thread in b.

Usually you use the posix "select" call to handle this kind of code.

Tom



Relevant Pages

  • Re: is cin always the keyboards input?
    ... the whole point of 'cin' is to keep this detail hidden from you. ... > input stream) as cin. ... testdatamaker outputs strings every second, ...
    (comp.lang.cpp)
  • Re: std::cin.ignore() and std::cin.clear()
    ... So what does cleardo anyway, if not clear all cin data? ... It clears the error state of the stream. ... The extracts an unlimited amount of characters (the max is a sentinel ... C++ FAQ: http://www.parashift.com/c++-faq-lite/ ...
    (comp.lang.cpp)
  • Re: cin error recovery
    ... cin>> i1; ... > When stream input encounters an illegal character, ... > have to be on separate lines. ...
    (comp.lang.cpp)
  • Re: Wierd newbie problem
    ... > You should flush cout before reading from cin. ... > it's possible for the text to not actually display ... > endl writes a newline and flushes the stream. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Wierd newbie problem
    ... You should flush cout before reading from cin. ... endl writes a newline and flushes the stream. ...
    (alt.comp.lang.learn.c-cpp)