reading from either cin or file

  • Thread starter Christof Warlich
  • Start date
C

Christof Warlich

Hi,

I want my program to either read from cin or from a file, if present.
Below is the solution I ended up with, but it really looks clumpsy.
Couldn't this be done in a more elegant way?

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
if(argc > 2) {
cerr << argv[0] << " is a filter or expects one input file.\n";
exit(EXIT_FAILURE);
}
ifstream instream;
istream *tmp;
if(argc == 2) {
instream.open (argv[1], fstream::in);
if(instream.fail()) {
cerr << "Failed to open file " << argv[1] << ".\n";
exit(EXIT_FAILURE);
}
tmp = &instream;
}
else {
tmp = &cin;
}
istream &in = *tmp;
string line;
while(getline(in, line)) {
// do something, e.g.:
cout << line << endl;
}
if(argc == 2) {
instream.close();
}
}

Thanks for any suggestions,

Christof
 
G

Gert-Jan de Vos

I want my program to either read from cin or from a file, if present.
Below is the solution I ended up with, but it really looks clumpsy.
Couldn't this be done in a more elegant way?

I suggest to use a function as a basic level of indirection like this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
     if(argc > 2) {
         cerr << argv[0] << " is a filter or expects one input file.\n";
         exit(EXIT_FAILURE);
     }
     if(argc == 2) {
ifstream instream(argv[1]);
         if(instream.fail()) {
             cerr << "Failed to open file " << argv[1] << "..\n";
             exit(EXIT_FAILURE);
         }
         DoSomething(instream);
     }
     else {
         DoSomething(cin);
     }
}

void DoSomething(istream& in)
{
     string line;
     while(getline(in, line)) {
         // do something, e.g.:
         cout << line << endl;
     }
}
 
C

Christof Warlich

Gert-Jan de Vos said:
I want my program to either read from cin or from a file, if present.
Below is the solution I ended up with, but it really looks clumpsy.
Couldn't this be done in a more elegant way?

I suggest to use a function as a basic level of indirection like this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
if(argc > 2) {
cerr << argv[0] << " is a filter or expects one input file.\n";
exit(EXIT_FAILURE);
}
if(argc == 2) { ifstream instream(argv[1]);
if(instream.fail()) {
cerr << "Failed to open file " << argv[1] << ".\n";
exit(EXIT_FAILURE);
} DoSomething(instream);
}
else { DoSomething(cin);
}
}

void DoSomething(istream& in)
{
string line;
while(getline(in, line)) {
// do something, e.g.:
cout << line << endl;
}
}

Yes, that's much better. I was so upset that I could not directly
convert between istream and ifstream that I thought that it _must_
somehow be possible. But after all, a file should be closed
at the end, while cin should not, which makes (one of) the differences
between these two types. Thus, handling things your way is the right
approach. Thanks for the suggestion.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,829
Messages
2,569,737
Members
45,521
Latest member
maryb

Latest Threads

Top