is cin always the keyboard's input?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bob Smith

    is cin always the keyboard's input?

    question in subject.
    does the standard say anything about this or is it platform dependent?
    any advice much appeciated
    /B

  • stephan beal

    #2
    Re: is cin always the keyboard's input?

    Bob Smith wrote:
    [color=blue]
    > question in subject.
    > does the standard say anything about this or is it platform dependent?
    > any advice much appeciated[/color]

    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:


    --
    ----- stephan beal
    Registered Linux User #71917 http://counter.li.org
    I speak for myself, not my employer. Contents may
    be hot. Slippery when wet. Reading disclaimers makes
    you go blind. Writing them is worse. You have been Warned.

    Comment

    • tom_usenet

      #3
      Re: is cin always the keyboard's input?

      On Wed, 15 Oct 2003 16:00:36 +0300, Bob Smith <bobsmith@jippi i.fi>
      wrote:
      [color=blue]
      >question in subject.
      >does the standard say anything about this or is it platform dependent?[/color]

      Platform dependent. Often input is a file anyway:

      cat "file.txt" | myprog

      The above pipes a file into the standard input of myprog (on unix at
      least). Alternatively, cin might be a serial port connection (on an
      embedded device), or a telepathic connection to your brain. It is just
      the standard stream-based input to a program.

      Tom

      Comment

      • Bob Smith

        #4
        Re: is cin always the keyboard's input?



        stephan beal wrote:
        [color=blue]
        > Bob Smith wrote:
        >
        >[color=green]
        >>question in subject.
        >>does the standard say anything about this or is it platform dependent?
        >>any advice much appeciated
        >>[/color]
        >
        > 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[/color]


        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() ){
        m_reading = true;
        qDebug( "reading... ");
        QxEvent e;
        while( cin >> e ) {
        m_event_queue.p ush( e );
        counter++;
        }
        qDebug( "...read!") ;
        m_reading = false;
        }else{
        qDebug("..no data" );
        }
        }else{
        qDebug("already reading, return to caller");
        }
        qDebug("ready") ;
        </snip>



        Now, trying to output data from one program, to this program, like
        ../testdatamaker|./eventlogger

        ( testdatamaker is a program for making up testdata for eventlogger )

        testdatamaker outputs strings every second, and eventlogger polls the
        cin stream continuously, but it never receives any data, it always
        returns with "no data".

        So the whole idea with my application is that it should read the input
        stream, that being any output from any program, piped, and make display
        data out of it.

        I feel silly to ask but what is going wrong ?*s*

        any help *very* much appreciated.
        thank's
        /B

        Comment

        • stephan beal

          #5
          Re: is cin always the keyboard's input?

          Bob Smith wrote:[color=blue]
          > 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.[/color]
          ....[color=blue]
          >
          > I feel silly to ask but what is going wrong ?*s*
          >
          > any help *very* much appreciated.[/color]

          i'm not a master of streams, so i don't have any suggestions except:
          - have you tried using one of Qt's stream classes instead of std::istream?
          - are the input fields properly terminated? (i can't say what QxEvent
          expects there.) i'm assuming you're using ostream << QxEvent to create the
          records, in which case the answer would of course be, "yes."

          i can't find QxEvent in the online docs at trolltech, so haven't read up on
          this class.


          redirs me to:


          --
          ----- stephan beal
          Registered Linux User #71917 http://counter.li.org
          I speak for myself, not my employer. Contents may
          be hot. Slippery when wet. Reading disclaimers makes
          you go blind. Writing them is worse. You have been Warned.

          Comment

          • Stewart Gordon

            #6
            Re: is cin always the keyboard's input?

            While it was 15/10/03 2:00 pm throughout the UK, Bob Smith sprinkled
            little black dots on a white screen, and they fell thus:
            [color=blue]
            > question in subject.
            > does the standard say anything about this or is it platform dependent?
            > any advice much appeciated[/color]

            Standard C++ knows nothing of keyboards.

            cin is the standard input, whatever that may be. Typical examples are
            console input, a pipe or a file.

            And even console input is seldom the keyboard directly. It is generally
            a mechanism that reads input lines and then transmits them to the
            program, line by line. Even these input lines need not come straight
            from the keyboard - e.g. if the console is in a GUI setting, chances are
            it supports copy and paste.

            Stewart.

            --
            My e-mail is valid but not my primary mailbox. Please keep replies on
            on the 'group where everyone may benefit.

            Comment

            • tom_usenet

              #7
              Re: is cin always the keyboard's input?

              On Wed, 15 Oct 2003 16:18:53 +0300, Bob Smith <bobsmith@jippi i.fi>
              wrote:
              [color=blue]
              >
              >
              >stephan beal wrote:
              >[color=green]
              >> Bob Smith wrote:
              >>
              >>[color=darkred]
              >>>question in subject.
              >>>does the standard say anything about this or is it platform dependent?
              >>>any advice much appeciated
              >>>[/color]
              >>
              >> 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[/color]
              >
              >
              >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() ){[/color]

              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.
              [color=blue]
              > m_reading = true;
              > qDebug( "reading... ");
              > QxEvent e;
              > while( cin >> e ) {
              > m_event_queue.p ush( e );
              > counter++;
              > }[/color]

              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;
              }
              [color=blue]
              > qDebug( "...read!") ;
              > m_reading = false;
              > }else{
              > qDebug("..no data" );
              > }
              > }else{
              > qDebug("already reading, return to caller");
              > }
              > qDebug("ready") ;
              ></snip>
              >[/color]

              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.p ush( 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

              Comment

              • Rolf Magnus

                #8
                Re: is cin always the keyboard's input?

                tom_usenet wrote:
                [color=blue]
                > in_avail will generally be 0 if you haven't attempted a read operation[/color]

                Stroustrup says something different in TC++PL. According to him, you can
                use in_avail _before_ a read attempt to find out if that read operation
                would block.

                Comment

                • Ron Natalie

                  #9
                  Re: is cin always the keyboard's input?


                  "Rolf Magnus" <ramagnus@t-online.de> wrote in message news:bmk20e$kj1 $05$1@news.t-online.com...[color=blue]
                  > tom_usenet wrote:
                  >[color=green]
                  > > in_avail will generally be 0 if you haven't attempted a read operation[/color]
                  >
                  > Stroustrup says something different in TC++PL. According to him, you can
                  > use in_avail _before_ a read attempt to find out if that read operation
                  > would block.
                  >[/color]
                  He does not say that and Rolf is right. What Stroustrup says is that if in_avail
                  is positive, then you won't block. The inverse is not true, that if in_avail is zero
                  you will block.

                  in_avail only tells you if there is characters in the stream's buffer. While you can
                  be guaranteed of reading that many characters without blocking (because they're
                  already in the buffer). However if it is zero or negative, it means a low-level read will have
                  to occur to get something in the buffer. Whether this will block or not is unknown
                  to the stream buffer classes.

                  As Rolf said, if you open a stream and you haven't done any reads, there's nothing
                  in the buffer and in_avail will be zero. The same is probably true if you read exactly
                  in_avail characters later.


                  Comment

                  • Bob Smith

                    #10
                    Re: is cin always the keyboard's input?



                    Ron Natalie wrote:
                    [color=blue]
                    > "Rolf Magnus" <ramagnus@t-online.de> wrote in message news:bmk20e$kj1 $05$1@news.t-online.com...
                    >[color=green]
                    >>tom_usenet wrote:
                    >>
                    >>[color=darkred]
                    >>>in_avail will generally be 0 if you haven't attempted a read operation
                    >>>[/color]
                    >>Stroustrup says something different in TC++PL. According to him, you can
                    >>use in_avail _before_ a read attempt to find out if that read operation
                    >>would block.
                    >>
                    >>[/color]
                    > He does not say that and Rolf is right. What Stroustrup says is that if in_avail
                    > is positive, then you won't block. The inverse is not true, that if in_avail is zero
                    > you will block.
                    >
                    > in_avail only tells you if there is characters in the stream's buffer. While you can
                    > be guaranteed of reading that many characters without blocking (because they're
                    > already in the buffer). However if it is zero or negative, it means a low-level read will have
                    > to occur to get something in the buffer. Whether this will block or not is unknown
                    > to the stream buffer classes.
                    >
                    > As Rolf said, if you open a stream and you haven't done any reads, there's nothing
                    > in the buffer and in_avail will be zero. The same is probably true if you read exactly
                    > in_avail characters later.
                    >
                    >
                    >[/color]

                    Hi again,
                    here is some code
                    <snip>

                    //testdatamaker
                    #include <iostream>
                    #include <strstream>
                    #include <unistd.h>
                    int main(void){
                    for ( int c = 0; c < 100;c++){
                    sleep(1);
                    strstream s;
                    s << "key " << c << ":data->" << c << endl;
                    cout << s.str();
                    }
                    }







                    //testdatasink
                    #include <iostream>
                    int main(void){
                    char c;
                    while ( cin >> c ) cout << c;
                    }


                    ../testdatamaker|./testdatasink
                    doesn't work because the testdatamaker sleeps one second for 100 times
                    and doesn't flush teh cout.


                    //new testdatamaker
                    ....
                    cout << s.str();
                    cout.flush();//<<--note
                    ....


                    ../testdatamaker|./testdatasink

                    now works.the testdatasink receives the data in real time.


                    let's test in_avail()
                    ///test in_avail()
                    #include <iostream>
                    #include <unistd.h>
                    bool has_data();
                    int main(void){
                    while( 1 ){
                    if ( has_data() ){
                    char c;
                    while( cin >> c ) cout << c;
                    }else{
                    cout << "no data..." << endl;
                    sleep(1);
                    }

                    }
                    }
                    bool has_data(){
                    cout << "cin.rdbuf( )->in_avail() returns:" << cin.rdbuf()->in_avail()
                    << endl;
                    return cin.rdbuf()->in_avail();
                    }


                    always returns "no data". has_data() always gives zero( 0 ) calling
                    cin.rdbuf()->in_avail().
                    in_avail() is broken on my linux box. or perhaps poorly implemented.
                    need to look for a new way of getting piped data.

                    any help much appreciated.

                    /B

                    Comment

                    • tom_usenet

                      #11
                      Re: is cin always the keyboard's input?

                      On Thu, 16 Oct 2003 10:49:37 +0300, Bob Smith <bobsmith@jippi i.fi>
                      wrote:
                      [color=blue]
                      >
                      >
                      >Ron Natalie wrote:
                      >[color=green]
                      >> "Rolf Magnus" <ramagnus@t-online.de> wrote in message news:bmk20e$kj1 $05$1@news.t-online.com...
                      >>[color=darkred]
                      >>>tom_usenet wrote:
                      >>>
                      >>>
                      >>>>in_avail will generally be 0 if you haven't attempted a read operation
                      >>>>
                      >>>Stroustrup says something different in TC++PL. According to him, you can
                      >>>use in_avail _before_ a read attempt to find out if that read operation
                      >>>would block.
                      >>>
                      >>>[/color]
                      >> He does not say that and Rolf is right. What Stroustrup says is that if in_avail
                      >> is positive, then you won't block. The inverse is not true, that if in_avail is zero
                      >> you will block.
                      >>
                      >> in_avail only tells you if there is characters in the stream's buffer. While you can
                      >> be guaranteed of reading that many characters without blocking (because they're
                      >> already in the buffer). However if it is zero or negative, it means a low-level read will have
                      >> to occur to get something in the buffer. Whether this will block or not is unknown
                      >> to the stream buffer classes.
                      >>
                      >> As Rolf said, if you open a stream and you haven't done any reads, there's nothing
                      >> in the buffer and in_avail will be zero. The same is probably true if you read exactly
                      >> in_avail characters later.
                      >>
                      >>
                      >>[/color]
                      >
                      >Hi again,
                      >here is some code[/color]
                      [color=blue]
                      >./testdatamaker|./testdatasink
                      >doesn't work because the testdatamaker sleeps one second for 100 times
                      >and doesn't flush teh cout.
                      >
                      >
                      >//new testdatamaker
                      >...
                      > cout << s.str();
                      > cout.flush();//<<--note[/color]

                      Right, you need to flush. You don't need the intermediary strstream
                      though. You also were missing a "using namespace std;" at the top,
                      that suggests to me that you are using a very old compiler.
                      [color=blue]
                      >./testdatamaker|./testdatasink
                      >
                      >now works.the testdatasink receives the data in real time.
                      >
                      >
                      >let's test in_avail()
                      >///test in_avail()
                      >#include <iostream>
                      >#include <unistd.h>
                      >bool has_data();
                      >int main(void){
                      > while( 1 ){
                      > if ( has_data() ){
                      > char c;
                      > while( cin >> c ) cout << c;
                      > }else{
                      > cout << "no data..." << endl;
                      > sleep(1);
                      > }
                      >
                      > }
                      >}
                      >bool has_data(){
                      > cout << "cin.rdbuf( )->in_avail() returns:" << cin.rdbuf()->in_avail()
                      ><< endl;
                      > return cin.rdbuf()->in_avail();
                      >}
                      >
                      >
                      >always returns "no data". has_data() always gives zero( 0 ) calling
                      >cin.rdbuf()->in_avail().
                      >in_avail() is broken on my linux box.[/color]

                      No, if you read my previous post it may legitimately return 0 under
                      those circumstances.
                      [color=blue]
                      > or perhaps poorly implemented.[/color]

                      Possibly - the function "showmanyc" can be overrided by the
                      implementer to try to work out how many characters are waiting. If the
                      streambuf doesn't have any characters buffered, it will return
                      "showmanyc" when you call "in_avail".
                      [color=blue]
                      >need to look for a new way of getting piped data.[/color]

                      What are your requirements? What is wrong with your original blocking
                      program? As I said before, you have to make stdin a non-blocking
                      stream. e.g.

                      int result = fcntl(STDIN, F_SETFL, O_NONBLOCK);
                      or even better, use "select" on STDIN.

                      Tom

                      Comment

                      • Bob Smith

                        #12
                        Re: is cin always the keyboard's input?

                        >>//new testdatamaker[color=blue][color=green]
                        >>...
                        >> cout << s.str();
                        >> cout.flush();//<<--note
                        >>[/color]
                        >
                        > Right, you need to flush. You don't need the intermediary strstream
                        > though. You also were missing a "using namespace std;" at the top,
                        > that suggests to me that you are using a very old compiler.[/color]


                        I need to flush, yes. now we are talking...

                        my compiler is ancient.

                        [color=blue]
                        >
                        >[color=green]
                        >>./testdatamaker|./testdatasink
                        >>
                        >>now works.the testdatasink receives the data in real time.
                        >>
                        >>
                        >>let's test in_avail()
                        >>///test in_avail()
                        >>#include <iostream>
                        >>#include <unistd.h>
                        >>bool has_data();
                        >>int main(void){
                        >> while( 1 ){
                        >> if ( has_data() ){
                        >> char c;
                        >> while( cin >> c ) cout << c;
                        >> }else{
                        >> cout << "no data..." << endl;
                        >> sleep(1);
                        >> }
                        >>
                        >> }
                        >>}
                        >>bool has_data(){
                        >> cout << "cin.rdbuf( )->in_avail() returns:" << cin.rdbuf()->in_avail()
                        >><< endl;
                        >> return cin.rdbuf()->in_avail();
                        >>}
                        >>
                        >>
                        >>always returns "no data". has_data() always gives zero( 0 ) calling
                        >>cin.rdbuf()->in_avail().
                        >>in_avail() is broken on my linux box.
                        >>[/color]
                        >
                        > No, if you read my previous post it may legitimately return 0 under
                        > those circumstances.[/color]


                        Thank's tom now I understand.
                        ( sorry it didn't make it all through the first time you explained )


                        [color=blue]
                        >
                        >[color=green]
                        >>or perhaps poorly implemented.
                        >>[/color]
                        >
                        > Possibly - the function "showmanyc" can be overrided by the
                        > implementer to try to work out how many characters are waiting. If the
                        > streambuf doesn't have any characters buffered, it will return
                        > "showmanyc" when you call "in_avail".
                        >
                        >[color=green]
                        >>need to look for a new way of getting piped data.
                        >>[/color]
                        >
                        > What are your requirements? What is wrong with your original blocking
                        > program? As I said before, you have to make stdin a non-blocking
                        > stream. e.g.
                        >
                        > int result = fcntl(STDIN, F_SETFL, O_NONBLOCK);
                        > or even better, use "select" on STDIN.[/color]


                        now we are talking, that is something useful for me.

                        My intention is to create an application for showing of debug stream
                        data from application(s) in development, or application(s) in the run
                        outputting debug live data. So my application may (or may not, depending
                        on if the user is interested in seeing the debug data ) wait on
                        cin/stdin until the data is there to be read. Further, the applciation
                        must be able to cancel waiting, therefore it needs non-blocking access
                        to stdin/cin, because there may be data, or not data, and teh user may
                        have chosen to read, or not to read. Those are gui options. That's why I
                        can't attempt to read when no data is there because the read will block
                        indefinitly, or until there is data to be read.

                        Thank's tom, and wish you a nice day
                        Thank you all the others, too.

                        /B

                        [color=blue]
                        >
                        > Tom
                        >[/color]

                        Comment

                        Working...