IAE
IAE

Reputation: 2243

How to Determine if STDIN is Empty?

I'm writing an emulator for my Operating Systems course. The problem I have is that we need to get all our .job files (they are like application programs being fed to the emulator) from STDIN and read them in.

Call:

./RMMIX < aJob.job

I just slurp it with

while(getline(std::cin, line)) 

line by line. The problem is, if I do not put anything to STDIN, then cin will wait for user input- NOT what I want. I need the program to recognize a lack of text on STDIN and terminate, not wait for user input instead.

I have determined that I can query the length like so:

size_t beg = std::cin.tellg();
std::cin.seekg(0, std::ios_base::end);
size_t end = std::cin.tellg();
std::cin.seekg(0, std::ios_base::beg);

and terminate if std::cin has a length of 0.

Are there any other solutions to this? Is this a portable solution?

Upvotes: 7

Views: 5905

Answers (4)

hammar
hammar

Reputation: 139930

I don't think there's a platform independent way of doing this, but on Unix-based systems you should be able to do:

#include <unistd.h>
...

int main() {
    if (!isatty(0)) {
        // stdin is being streamed from a file or something else that's not a TTY.
    }

    ...
}

However, I think doing it via a command line option is the preferred approach.

Upvotes: 4

Wug
Wug

Reputation: 13196

You can press Ctrl+D on the command line to signal end-of-file for standard input on the running program.

This is desired behavior. Otherwise, if programs exited immediately when no input remained, pipelines could randomly be broken by commands that were waiting on another command that had not been scheduled to run (and that had not produced any additional output), or that buffered output and emitted it all at once, like sort does.

When using io redirection to pull stdin from a file via something like ./RMMIX < file.txt, this end-of-file condition is signaled automatically when there is no more data left in the file. For input read from a terminal, waiting is probably the desired behavior.

Upvotes: 0

deong
deong

Reputation: 3870

You might also look at this http://www.programmersheaven.com/mb/CandCPP/232821/232821/non-blocking-reads-on-stdin/ for an idea that comes at the problem from another direction -- don't check the number of bytes on the stream, but instead just make the read succeed immediately and then check to see if anything was read.

Upvotes: 2

user2100815
user2100815

Reputation:

You need to redesign your program. Instead of reading from standard input, read from a named file, who's name you provide on the command line. Then instead of:

./RMMIX < aJob.job

you say:

./RMMIX aJob.job

This is much easier and more portable than trying to determine if there is anything in standard input.

Upvotes: 2

Related Questions