Reputation: 2243
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
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
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
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
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