Como redirecionar cin e cout para arquivos?

Respostas:

219

Aqui está um exemplo prático do que você deseja fazer. Leia os comentários para saber o que cada linha do código faz. Eu testei no meu pc com o gcc 4.6.1; Funciona bem.

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

Você pode salvar e redirecionar em apenas uma linha como:

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

Aqui std::cin.rdbuf(in.rdbuf())define std::cin'sbuffer para in.rdbuf()e, em seguida, retorna o buffer antigo associado std::cin. O mesmo pode ser feito com std::cout- ou qualquer fluxo para esse assunto.

Espero que ajude.

Nawaz
fonte
4
Preciso fechar os arquivos antes de redefinir cin e cout para o IO padrão?
updogliu
3
@updogliu: Não. Se desejar, você pode usar ine outpara ler e escrever para in.txte out.txtrespectivamente. Além disso, os arquivos serão fechados automaticamente quando ine ficarão outfora do escopo.
Nawaz
Gosto dessa solução freopenporque não consigo mais me stdoutrecuperar se eu usar freopen. stackoverflow.com/questions/26699524/…
xxks-kkk
88

Apenas escreva

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

int main()
{
    freopen("output.txt","w",stdout);
    cout<<"write in file";
    return 0;
}
Tsotne Tabidze
fonte
14
Isso está redirecionando stdout, não cout.
updogliu
5
Isso também redirecionará o printf, o que, em alguns casos, pode ser uma coisa boa.
JDiMatteo
5
@AkshayLAradhya Não quando você define std::sync_with_studio(false);, embora por padrão esteja definido como true.
Vsoftco 28/10
2
@ PřemyslŠťastný por quê?
Reggaeguitar
4
Se as respostas tivessem a mesma funcionalidade, o equivalente em C ++ seria ofstream out("out.txt"); cout.rdbuf(out.rdbuf());- apenas uma linha extra e é portátil. Não soooo muito mais simples :)
nevelis
19

Aqui está um trecho de código curto para sombreamento 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;
}

Isso oferece um benefício adicional de que os fluxos simples são mais rápidos que os fluxos stdio sincronizados. Mas isso funciona apenas para o escopo da função única.

O redirecionamento global cin / cout pode ser escrito 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();
}

Observe que ios_base::sync_with_stdiotambém redefine std::cin.rdbuf. Então a ordem é importante.

Consulte também Significado da ios_base :: sync_with_stdio (false); cin.tie (NULL);

Os fluxos Std io também podem ser facilmente sombreados no escopo do arquivo único, o que é útil para a programação 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();
}

Mas, neste caso, temos que escolher as stddeclarações uma por uma e evitar, using namespace std;pois isso daria erro de ambiguidade:

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 também Como você usa corretamente os namespaces em C ++? , Por que "usar o namespace std" é considerado uma má prática? e Como resolver uma colisão de nomes entre um espaço para nome C ++ e uma função global?

Vadzim
fonte
15

supondo que o nome do seu programa de compilação seja x.exe e $ seja o shell ou prompt do sistema

$ x <infile >outfile 

terá entrada de infile e saída para outfile.

Ahmed Eid
fonte
Isso não está relacionado ao C ++ e falha em qualquer exemplo não trivial, por exemplo, quando seu programa gera processos filhos que gravam no console. Pelo menos esse é o problema que encontrei quando tentei esse redirecionamento, por isso estou aqui.
ashrasmun
5

Tente isso para redirecionar o cout para o arquivo.

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

Leia o artigo completo Use std :: rdbuf para redirecionar cin e cout

HaseeB Mir
fonte
1
A pergunta foi respondida há quase 6 anos (em 2012), mas você adicionou uma resposta agora em 2018. Sua resposta é igual à resposta aceita. Então, eu estou me perguntando por que você postou isso quando não tinha nada novo para adicionar?
Nawaz
Minha resposta destaca apenas a versão cout especialmente e a resposta detalhada é fornecida no link abaixo.
precisa saber é o seguinte
O que há de novo na sua resposta que não está presente na resposta aceita ?
Nawaz
2
Minha resposta não se mistura redirecionamento de ambos cout e cin, minha versão separa para torná-lo mais legível
Haseeb Mir