views:

433

answers:

2

I need to write a program that reads in either from ifstream or cin, depending on parameters passed into the program at runtime.

I was planning on doing the following:

 istream in;

 if(argv[1] == "cin")
 {
      in = cin;
 }
 else
 {
      ifStream inFile;
      inFile.open(argv[1].c_str());
      in = inFile;
 }

However, istream in protected, and I can't declare istream in. Is there a way to declare such a generic in stream?

+3  A: 

Try with an istream* instead. Note, however, that you have to change your code slightly. Using pointers you have to preserve the memory area of the object that you're pointing. In other words, the "inFile" variable cannot be declared there, as it won't exist out of the else. The code could be, then:

 istream* in;
 ifStream inFile;

 if(!strcmp(argv[1],"cin"))
 {
      in = &cin;
 }
 else
 {
      inFile.open(argv[1]);
      in = &inFile;
 }
 // use *in

(Note also the modifications in the string handling. I modified them as an example.)

Diego Sevilla
Ok, I tried that, however the following code produces the following error:CODE:while(*in.good()) { string line; getline(*in, line); cout << line; } ERROR:request for member 'good' in 'in', which is of non-class type 'std::istream*'
segfault
Use either `(*in).good` or `in->good`. Just take a seat and be more familiar with the C++ syntax. You'll save a lot of hours :)
Diego Sevilla
oh, ok. Thanks for the help. I just wasn't thinking right.
segfault
A: 

An alternative design is to write your code using cin, and then use input redirection when running the program if you want to accept input from a file. This doesn't answer your exact question, but it is a simpler design for the case you presented.

For example, instead of

program.exe cin

you would just run

program.exe

and instead of

program.exe myfile.txt

you would run

program.exe < myfile.txt

This works on *nix and Windows.

Jay Michaud