¿Cómo redirigir cin y cout a los archivos?

Respuestas:

219

Aquí hay un ejemplo práctico de lo que quieres hacer. Lea los comentarios para saber qué hace cada línea del 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
}

Puede guardar y redirigir en una sola línea como:

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

Aquí std::cin.rdbuf(in.rdbuf())establece el std::cin'sbúfer en in.rdbuf()y luego devuelve el viejo búfer asociado con std::cin. Lo mismo se puede hacer con std::cout, o cualquier transmisión para el caso.

Espero que ayude.

Nawaz
fuente
44
¿Necesito cerrar los archivos antes de restablecer cin y cout a IO estándar?
updogliu
3
@updogliu: No. Si lo desea, puede usar iny outpara leer y escribir, in.txty out.txtrespectivamente. Además, los archivos se cerrarán automáticamente cuando iny outsalir de su ámbito.
Nawaz
Me gusta esta solución sobre la anterior freopenporque ya no puedo recuperar mi stdoutespalda si la uso freopen. stackoverflow.com/questions/26699524/…
xxks-kkk
88

Solo escribe

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

int main()
{
    freopen("output.txt","w",stdout);
    cout<<"write in file";
    return 0;
}
Tsotne Tabidze
fuente
14
Eso es redirigir stdout, no cout.
updogliu
55
Esto también redirigirá printf, que en algunos casos puede ser algo bueno.
JDiMatteo
55
@AkshayLAradhya No cuando lo configura std::sync_with_studio(false);, aunque de manera predeterminada está configurado como true.
vsoftco
2
@ PřemyslŠťastný ¿por qué?
reggaeguitar 03 de
44
Si las respuestas fueran iguales en funcionalidad, el equivalente en C ++ de esto sería ofstream out("out.txt"); cout.rdbuf(out.rdbuf());: solo una línea adicional y es portátil. No es
muuuucho
19

Aquí hay un breve fragmento de código para sombrear cin / cout útil para programar concursos:

#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 proporciona un beneficio adicional de que los flujos simples son más rápidos que los flujos estándar sincronizados. Pero esto funciona solo para el alcance de una sola función.

La redirección global de 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 ios_base::sync_with_stdiotambién se restablece std::cin.rdbuf. Entonces el orden importa.

Consulte también Significado de ios_base :: sync_with_stdio (false); cin.tie (NULL);

Las transmisiones estándar también se pueden sombrear fácilmente para el alcance de un solo archivo, lo cual 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 las stddeclaraciones una por una y evitarlas, using namespace std;ya que daría un 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
                   ^

Consulte también ¿Cómo utiliza correctamente los espacios de nombres en C ++? , ¿Por qué "usar el espacio de nombres estándar" se considera una mala práctica? y ¿Cómo resolver una colisión de nombres entre un espacio de nombres C ++ y una función global?

Vadzim
fuente
15

suponiendo que el nombre del programa de compilación es x.exe y $ es el intérprete de comandos del sistema

$ x <infile >outfile 

tomará la entrada del archivo y saldrá al archivo externo.

Ahmed Eid
fuente
Eso no está relacionado con C ++ y falla en cualquier ejemplo no trivial, por ejemplo, cuando su programa genera procesos secundarios que escriben en la consola. Al menos ese es el problema que encontré cuando intenté dicha redirección, de ahí por qué estoy aquí.
ashrasmun
5

Intente esto para redirigir cout al archivo.

#include <iostream>
#include <fstream>

int main()
{
    /** backup cout buffer and redirect to out.txt **/
    std::ofstream out("out.txt");

    auto *coutbuf = std::cout.rdbuf();
    std::cout.rdbuf(out.rdbuf());

    std::cout << "This will be redirected to file out.txt" << std::endl;

    /** reset cout buffer **/
    std::cout.rdbuf(coutbuf);

    std::cout << "This will be printed on console" << std::endl;

    return 0;
}

Leer artículo completo Use std :: rdbuf para redirigir cin and cout

HaseeB Mir
fuente
1
La pregunta había sido respondida hace casi 6 años (en 2012), pero ahora ha agregado una respuesta en 2018. Su respuesta es la misma que la respuesta aceptada. Así que me pregunto por qué publicaste esto cuando no tenías nada nuevo que agregar.
Nawaz
Mi respuesta resalta solo la versión cout especialmente y la respuesta detallada se proporciona en el siguiente enlace.
HaseeB Mir
¿Qué hay de nuevo en su respuesta que no está presente en la respuesta aceptada ?
Nawaz
2
Mi respuesta no combina la redirección de cout y cin, mi versión se separa para que sea más legible
HaseeB Mir