18

You know the common stdio idiom that stdin is specified by a filename of "-", e.g.

if ((strcmp(fname, "-"))
    fp = fopen(fname);
else
    fp = stdin;

What's the best way to do this with an ifstream instance? I've received a bit of code that has an ifstream as part of a class and I'd like to add code to do the equivalent, something like:

if ( filename == "-")
    logstream = cin;  // **how do I do this*?*
else
    logstream.open( filename.c_str() );
Mark Harrison
  • 297,451
  • 125
  • 333
  • 465

2 Answers2

25

cin is not an ifstream, but if you can use istream instead, then you're in to win. Otherwise, if you're prepared to be non-portable, just open /dev/stdin or /dev/fd/0 or whatever. :-)


If you do want to be portable, and can make your program use istream, here's one way to do it:

struct noop {
    void operator()(...) const {}
};

// ...

shared_ptr<istream> input;
if (filename == "-")
    input.reset(&cin, noop());
else
    input.reset(new ifstream(filename.c_str()));

The noop is to specify a deleter that does nothing in the cin case, because, well, cin is not meant to be deleted.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
0
Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83
  • I wrote a very similar answer an hour ago, but then deleted it after re-reading this part of the question: "I've received a bit of code that has an ifstream as part of a class". The question's title is misleading in that it may be read as "how do I redirect cin to read from a file", but it is, IIUC, the reverse: The OP already has an ifstream and would like to redirect it to cin. – Éric Malenfant Jan 29 '10 at 16:03
  • Indeed. We cannot change the streambuf of an ifstream like that. As in Chris Jester-Young's solution, the exact type of the stream used needs to be changed. – Luc Hermitte Jan 29 '10 at 16:56