2012-04-14 25 views
96

¿Cómo puedo redirigir cin a in.txt y cout a out.txt?Cómo redirigir cin y cout a los archivos?

+6

redirección cin en una cadena: http://stackoverflow.com/questions/4925150/redirect-cin-to-a-string - redirección cout en una cadena: http: // stackoverflow.com/questions/1162068/redirect-both-cout-and-stdout-to-a-string-in-c-for-unit-testing –

Respuesta

159

Aquí hay un ejemplo de lo que quiere hacer. Lea los comentarios para saber qué hace cada línea en el código. Lo probé en mi pc con gcc 4.6.1; funciona bien.

#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 
} 

Se podría ahorrar y redirigir en una sola línea como:

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

Aquí std::cin.rdbuf(in.rdbuf()) conjuntos std::cin's buffer para in.rdbuf() y luego devuelve el búfer de edad asociada a std::cin. Lo mismo se puede hacer con std::cout — o cualquier corriente para el caso.

Espero que ayude.

+4

¿Debo cerrar los archivos antes de reiniciar cin y cout a IO estándar? – updogliu

+3

@updogliu: No. Si lo desea, puede usar 'in' y' out' para leer y escribir en, 'in.txt' y' out.txt' respectivamente. Además, los archivos se cerrarán automáticamente cuando 'in' y' out' salgan del alcance. – Nawaz

68

Sólo tiene que escribir

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

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

Eso está redirigiendo 'stdout', not' cout'. – updogliu

+3

Esto redirigirá printf también, lo que en algunos casos puede ser algo bueno. – JDiMatteo

+1

@updogliu según mi conocimiento, stdout y cout están sincronizados todo el tiempo –

12

Asumiendo que su nombre compila prog es x.exe y $ es el shell del sistema o pronta

$ x <infile >outfile 

tomará la entrada del archivo de entrada y de salida de archivo de salida.

8

Aquí es un fragmento de código corto para sombrear CIN/cout útil para concursos de programación:

#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; 
} 

Esto da beneficio adicional de que fstreams lisos son más rápidas que las corrientes stdio sincronizados. Pero esto funciona solo para el alcance de una función.

redirección Global CIN/cout se puede escribir como:

#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(); 
} 

Tenga en cuenta que también se restablece ios_base::sync_with_stdiostd::cin.rdbuf. Entonces el orden importa.

Ver también Significance of ios_base::sync_with_stdio(false); cin.tie(NULL);

Std corrientes io también pueden quedar sombreados facilidad para el alcance de una sola fila, que es útil para la programación competitiva:

#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(); 
} 

Pero en este caso tenemos que elegir std declaraciones uno por uno y evitar using namespace std; ya que daría error de ambigüedad:

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 
       ^

Ver también How do you properly use namespaces in C++?, Why is "using namespace std" considered bad practice? y How to resolve a name collision between a C++ namespace and a global function?