Newbie C++ programmer here. I’m trying to write a command line application that takes two arguments, an input file and an output file. However, if the input file or the output file name is “-“, I need the program to read/output to standard input/output instead. My problem is that in C++, I don’t know how to do this without the compiler not knowing that the input/output streams are initialized. Here’s the code I have.
if(argv[1] == "-") {
istream input;
cout << "Using standard input" << endl;
}
else {
ifstream input;
cout << "Using input file " << argv[1] << endl;
input.open(argv[1], ios::in);
if(!input) {
cerr << "Cannot open input file '" << argv[1]
<< "', it either does not exist or is not readable." << endl;
return 0;
}
}
if(argv[2] == "-") {
ostream output;
cout << "Using standard output" << endl;
}
else {
ofstream output;
cout << "Using output file " << argv[2] << endl;
output.open(argv[2], ios::out);
if(!output) {
cerr << "Cannot open output file '" << argv[2] << "' for writing."
<< " Is it read only?" << endl;
return 0;
}
}
From here I cannot call the operator >> on input, because, I’m guessing, the compiler doesn’t know it’s been initialized.
You can use a reference to a stream, and then initialize it to refer to either a file stream or standard input or output. The initialization has to happen in a single command, though, so you’ll have to declare the file streams even if you don’t use them.
Notice the
&in the declarations ofinputandoutput. They indicate that we’re not declaring a separate stream object, but rather just declaring a reference to some other stream object, which we select conditionally based on the value ofargv[x].Then you can open the files, if you need to. The drawback is that we need to check for “-” strings twice instead of just once for each input or output.
Thereafter, you can read from
inputand write tooutput, and the files or the standard I/O streams will be used.Note the other changes I made to your code. First, I call
strcmpinstead of using the==operator; the operator doesn’t do what you think it does when comparing achar*with a literal. Next, when opening the file fails, I return 1 instead of 0. Zero indicates a successful program, whereas non-zero tells the OS that the program failed.