Search code examples
c++bashpiping

C++: Read from stdin as data is written into pipe


I have two C++ programs: one that prints a message to stdout, and the other that listens to stdin and prints all content from the stream. They are named out and in respectively.

out.cpp:

#include <iostream>

using namespace std;

int main() {
        cout<<"HELLO";
        usleep(1000000);
        cout<<"HELLO";
}

in.cpp:

#include <iostream>

using namespace std;

int main() {
        string input;
        while(cin>>input) {
                cout<<input;
        }
}

As it currently stands, piping the data from out to in waits for two seconds, then prints HELLOHELLO:

~$ ./out | ./in

#...two seconds later:
~$ ./out | ./in
HELLOHELLO~$

I'm sure this is a simple question, but is it possible for in to print each HELLO as out prints it? I've read that piped commands run concurrently, but I must be misunderstanding this concept for this particular situation. The desired performance is:

~$ ./out | ./in

#...one second later:
~$ ./out | ./in
HELLO

#...one second after that:
~$ ./out | ./in
HELLOHELLO~$

Solution

  • There's two issues going on here.

    The first is output buffering. You need to flush the output stream. Probably easiest way is cout.flush().

    The second is string reading reads whole words, and you're only outputting one, with a pause between.

    You either need to switch to character based input, or put a separator between the words.

    Character based input would look like this

    int main() {
            char input;
            while(cin>>input) {
                    cout<<input;
            }
    }
    

    Adding a separator would look like this:

    int main() {
            cout<<"HELLO";
            cout<<" ";
            usleep(1000000);
            cout<<"HELLO";
    }
    

    Note the additional space.