2012-04-14 4 views
96

Wie kann ich cin zu in.txt und cout zu out.txt umleiten?Wie cin und cout in Dateien umleiten?

+6

Redirect cin in einen String: http://stackoverflow.com/questions/4925150/redirect-cin-to-a-string - Redirect cout in einen String: http: // Stackoverflow.com/questions/1162068/redirect-sowohl-cout-und-stdout-zu-a-string-in-c-für-einheit-test –

Antwort

159

Hier ist ein Arbeitsbeispiel von dem, was Sie tun möchten. Lesen Sie die Kommentare, um zu erfahren, was jede Zeile im Code bewirkt. Ich habe es auf meinem PC mit gcc 4.6.1 getestet; es funktioniert gut.

#include <iostream> 
#include <fstream> 
#include <string> 

void f() 
{ 
    std::string line; 
    while(std::getline(std::cin, line)) //input from the file in.txt 
    { 
     std::cout << line << "\n"; //output to the file out.txt 
    } 
} 
int main() 
{ 
    std::ifstream in("in.txt"); 
    std::streambuf *cinbuf = std::cin.rdbuf(); //save old buf 
    std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt! 

    std::ofstream out("out.txt"); 
    std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf 
    std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt! 

    std::string word; 
    std::cin >> word;   //input from the file in.txt 
    std::cout << word << " "; //output to the file out.txt 

    f(); //call function 


    std::cin.rdbuf(cinbuf); //reset to standard input again 
    std::cout.rdbuf(coutbuf); //reset to standard output again 

    std::cin >> word; //input from the standard input 
    std::cout << word; //output to the standard input 
} 

Sie könnten speichern und umleiten in nur eine Zeile wie:

auto cinbuf = std::cin.rdbuf(in.rdbuf()); //save and redirect 

Hier std::cin.rdbuf(in.rdbuf()) Sätze std::cin's Puffer in.rdbuf() und dann kehrt der alte Puffer mit std::cin verbunden. Das gleiche kann mit std::cout — oder einem beliebigen Strom für diese Angelegenheit getan werden.

Hoffe, dass hilft.

+4

Muss ich die dateien schließen, bevor ich cin und cout auf standard IO? – updogliu

+3

@updogliu: Nein. Wenn Sie möchten, können Sie 'in' und' out' verwenden, um von 'in.txt' bzw.' out.txt' zu lesen und zu schreiben. Außerdem werden die Dateien automatisch geschlossen, wenn "in" und "out" den Gültigkeitsbereich verlassen. – Nawaz

68

Schreiben Sie einfach

#include <cstdio> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    freopen("output.txt","w",stdout); 
    cout<<"write in file"; 
    return 0; 
} 
+12

Das leitet 'stdout', nicht' cout' um. – updogliu

+3

Dadurch wird printf ebenfalls umgeleitet, was in manchen Fällen eine gute Sache sein kann. – JDiMatteo

+1

@updogliu Soweit ich weiß, sind stdout und cout ständig synchron –

12

Ihre compiles prog Name x.exe und $ ist die System-Shell oder Prompt

$ x <infile >outfile 

nehmen Eingabe von infile und ausgegeben zu outfile ist angenommen.

8

Hier ist ein kurzer Code-Schnipsel für Shadowing cin/cout nützlich für die Programmierung Wettbewerbe:

#include <bits/stdc++.h> 

using namespace std; 

int main() { 
    ifstream cin("input.txt"); 
    ofstream cout("output.txt"); 

    int a, b; 
    cin >> a >> b; 
    cout << a + b << endl; 
} 

Dies gibt zusätzlichen Vorteil, dass Ebene fstreams sind schneller als synchronisiert stdio Streams. Aber das funktioniert nur für den Umfang der einzelnen Funktion.

Globale cin/cout Umleitung kann geschrieben werden als:

#include <bits/stdc++.h> 

using namespace std; 

void func() { 
    int a, b; 
    std::cin >> a >> b; 
    std::cout << a + b << endl; 
} 

int main() { 
    ifstream cin("input.txt"); 
    ofstream cout("output.txt"); 

    // optional performance optimizations  
    ios_base::sync_with_stdio(false); 
    std::cin.tie(0); 

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

    func(); 
} 

Beachten Sie, dass ios_base::sync_with_stdio auch std::cin.rdbuf zurücksetzt. Also ist die Reihenfolge wichtig.

Siehe auch Significance of ios_base::sync_with_stdio(false); cin.tie(NULL);

Std io Ströme können auch leicht für den Umfang der einzelnen Datei beschattet werden, die für eine wettbewerbsfähige Programmierung nützlich ist:

#include <bits/stdc++.h> 

using std::endl; 

std::ifstream cin("input.txt"); 
std::ofstream cout("output.txt"); 

int a, b; 

void read() { 
    cin >> a >> b; 
} 

void write() { 
    cout << a + b << endl; 
} 

int main() { 
    read(); 
    write(); 
} 

Aber in diesem Fall wir std Erklärungen holen müssen eins nach dem anderen und vermeiden using namespace std; wie es Mehrdeutigkeit Fehler geben würde:

error: reference to 'cin' is ambiguous 
    cin >> a >> b; 
    ^
note: candidates are: 
std::ifstream cin 
    ifstream cin("input.txt"); 
      ^
    In file test.cpp 
std::istream std::cin 
    extern istream cin; /// Linked to standard input 
       ^

Siehe auch How do you properly use namespaces in C++?, Why is "using namespace std" considered bad practice? und How to resolve a name collision between a C++ namespace and a global function?