2017-04-19 19 views
5

Für den größten Teil meines Lebens, habe ich cstdio verwendet. Jetzt versuche ich auf iostream umzustellen.Run.exe und umleiten stdin und und

Angenommen, ich habe ein eigenes Programm namens „foo.cpp“, der wie folgt aussieht:

int main(){ // foo.cpp 
    int x; 
    std::cin >> x; 
    std::cout << x + 5 << "\n"; 
} 

In einem anderen Programm namens „bar.cpp“, rufe ich die foo ausführbar. In der Vergangenheit, wenn ich stdin und stdout in eine Datei umleiten wollte, würde ich freopen wie so verwenden:

int main(){ // bar.cpp, redirecting stdin and stdout 
    freopen("foo.in", "r", stdin); // Suppose "foo.in" contains a single integer "42" 
    freopen("foo.out", "w", stdout); 

    system("foo.exe"); // "foo.out" will contain "47" 
} 

Jetzt stringstreams Ich versuche std::cin und std::cout zu umleiten. Etwas wie folgt aus:

int main(){ // bar.cpp, redirecting cin and cout 
    std::istringstream instr("62"); 
    std::ostringstream outstr; 

    std::cin.rdbuf(instr.rdbuf()); 
    std::cout.rdbuf(outstr.rdbuf()); 

    system("foo.exe"); // outstr should contain "67" 
} 

Aber was ich gelernt habe, ist, dass std::cin und std::cout nicht umgeleitet wurde, als „foo.exe“ ausgeführt wird. Das Programm erwartet nun eine Benutzereingabe und druckt auf std::cout. Wenn die Ausführung von "foo.exe" durchgeführt wurde, blieben std::cin und std::cout innerhalb von "bar.cpp" immer noch an instr bzw. outstr umgeleitet.

Meine Frage ist, gibt es einen Weg, es mit iostream zu tun, wie ich es beabsichtigte, oder bin ich mit der Verwendung von freopen fest?

+1

Das Betriebssystem ist verantwortlich für die Verarbeitung der Ausgabe von ausführbaren Dateien. Die C++ - Sprache verfügt nicht über Funktionen zum Umleiten der Ausgabe. –

+1

Gemeinsame Lösungen für die gemeinsame Nutzung von Daten zwischen Programmen: Dateien, Sockets, Rohrleitungen (sagen Sie OS, um die Ausgabe eines anderen Programms in die Standardeingabe für Ihr Programm zu leiten), gemeinsame Speicherbereiche. Das Internet durchsuchen. –

+1

Haben Sie versucht, die gleichen Freopen-Anrufe zu machen? – stark

Antwort

1

Haben Sie nicht eine freopen Anruf in einer Weile gesehen. Das bringt einige alte Erinnerungen zurück.

Wie auch immer, ich denke, Sie sollten mit freopen bleiben. Die documentation Seite der Funktion heißt es wörtlich, dass dies eines der wichtigsten Anwendungsfälle ist:

Diese Funktion zum Umleiten vordefinierten Streams wie stdin besonders nützlich ist, stdout und Stderr auf bestimmte Dateien.

Ich glaube nicht, dass Sie nur die Umleitung mit iostream tun können, weil die iostream Bibliothek kein Äquivalent für die freopen Funktion hat.

Es ist interessant, obwohl, warum diese Lösung Sie versuchen nicht funktioniert:

std::cin.rdbuf(instr.rdbuf()); 
std::cout.rdbuf(outstr.rdbuf()); 

Vielleicht mit diesen beiden Linien beeinflussen Sie nur die RDBUF von std::cin und std::cout aus dem aktuellen Prozess und die Subprozess hat eine andere Instanz von std::cin und std::cout.

Die Informationen über Dateien werden scheinbar vom übergeordneten Prozess in den Unterprozess kopiert, wenn system aufgerufen wird. Deshalb sind die Änderungen, die Sie im Hauptprozess unter stdin und stdout mit freopen vornehmen, auch im Subprozess sichtbar.

Unabhängig, you should not use system, um ein Unterprogramm von Ihrem C++ - Hauptprogramm auszuführen.Wie Sie wahrscheinlich unter Windows sind (raten von foo.exe), würde ich diese example von Microsoft analysieren. Es wird erläutert, wie ein Unterprozess erstellt und mithilfe von Pipes die Eingabe und Ausgabe des Unterprogramms umgeleitet wird.

0

In Ihrem Beispielcode mit Freopen, Sie sind auf/von physischen Dateien umleiten, richtig? In Ihrem Beispielcode mit std :: istringstream und std :: ostringstream versuchen Sie, zu/aus dem Speicher umzuleiten, korrigieren? Physische Dateien sind nicht identisch mit Speicher. Speicher hat keine Dateideskriptoren. In Linux können Sie fmemopen wie in windows - C - create file in memory - Stack Overflow verwenden, aber das wird nicht mit C++ - Standardklassen wie std :: istringstream und std :: ostringstream helfen, noch würden Sie stdin und stdout zu/von fmemopen umleiten können, zum einen wegen fmemopen ist nicht in allen Betriebssystemen verfügbar. Die C++ - Standardklassen unterstützen diese Art von Dingen nicht; siehe c++ - Getting a FILE* from a std::fstream - Stack Overflow. std :: istream und std :: ostream könnten auf der C++ - Interace-Ebene wie std :: istringstream und std :: ostringstream aussehen, aber intern sind sie nicht kompatibel.