Search code examples
c++istream

Reading std::cin hangs if no pipe is provided


I have a function of the general form

void readStuff(std::istream& input){
    int var;
    while(input>>var){
        //... do stuff
    }
}

where input is passed as either std::cin or std::ifstream, depending on whether a command line option -c is set. Reading from file

myprog file.txt

works fine. If std::cin is used,

cat file.txt | myprog -c

that works fine as well. However, it hangs if the user tries

myprog -c

How can I handle this case from within my code? I've tried checking ifstream's flags, but in all cases they are 0 except for ifstream.good().


Solution

  • Your program isn't hanging; cin is just waiting for input from the terminal.

    When you piped cat command's stdout into your program's stdin, there was an EOF in your stdin. This would cause the eof flag to be set which in turn would cause while(input>>var) to fail; hence exiting the loop.

    When you execute your program directly from the terminal, cin keeps waiting for input from the terminal until the input stream is closed. You can exit your program by sending an EOF through the terminal which will close the input stream which in turn will break the loop in your code.

    If you want your program to exit if it is not in a pipe, you can check using isatty on POSIX systems and _isatty on Windows.