2010-01-29 6 views
16

Sie kennen das übliche stdiologische Idiom, das stdin durch einen Dateinamen von "-", z.C++: cin einer ifstream-Variablen zuweisen?

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

Was ist der beste Weg, dies mit einer ifstream Instanz zu tun? Ich habe ein Stück Code erhalten, der eine ifstream als Teil einer Klasse hat, und ich würde gerne Code hinzufügen, um das Äquivalent zu tun, so etwas wie:

if (filename == "-") 
    logstream = cin; // **how do I do this*?* 
else 
    logstream.open(filename.c_str()); 

Antwort

22

cin ist kein ifstream, aber wenn Sie können stattdessen istream verwenden, dann sind Sie in der Lage zu gewinnen. Andernfalls, wenn Sie bereit sind, nicht tragbar zu sein, öffnen Sie einfach /dev/stdin oder /dev/fd/0 oder was auch immer. :-)


Wenn Sie tun tragbar sein möchten, und können Ihr Programm verwenden istream, hier ist eine Möglichkeit, es zu tun machen:

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

// ... 

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

Die noop ist ein deleter zu spezifizieren, dass tut nichts in der cin Fall, denn, nun, cin ist nicht zum Löschen gedacht.

+0

danke ... das muss nur auf linux und osx portierbar sein, also/dev/stdin ist es! (seufz) –

+1

Dies zeigt, wie sich niemand jemals hingesetzt hat und einen halbwegs anständigen Satz von C++ - Bibliotheken gemacht hat. (Ich würde Boost sagen, wenn es nicht so viele Probleme mit der Versionierung hatte) –

+1

FWIW, mit C++ 11 anstatt 'noop()' zu 'reset' zu übergeben (und die Struktur zu definieren), ein einfaches (und lustig aussehendes) '[] (...) {}' tut es. – akim

0
  • Speichern der Anfangs streambuf of cin in eine Variable
  • Ändern der streambuf of cin zum one from the file.
  • Machen Sie, was Sie tun müssen
  • Und vergessen Sie nicht, cin streambuf vor dem Schließen der Datei wiederherzustellen - RAII kann helfen.
+0

Ich schrieb vor einer Stunde eine sehr ähnliche Antwort, löschte sie aber, nachdem ich diesen Teil der Frage erneut gelesen hatte: "Ich habe ein bisschen Code erhalten, der einen ifstream als Teil einer Klasse enthält". Der Titel der Frage ist insofern irreführend, als er wie "Wie leite ich cin aus einer Datei umzulesen" gelesen werden kann, aber es ist, IIUC, das Gegenteil: Das OP hat bereits einen ifstream und möchte es nach cin umleiten. –

+0

In der Tat. Wir können den Streambuf eines Ifstreams nicht ändern. Wie in Chris Jester-Youngs Lösung muss der genaue Typ des verwendeten Streams geändert werden. –