Как перенаправить cin и cout в файлы?


Ответы:


219

Вот рабочий пример того, что вы хотите сделать. Прочтите комментарии, чтобы узнать, что делает каждая строка кода. Я тестировал его на своем компьютере с помощью gcc 4.6.1; это работает отлично.

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

Вы можете сохранить и перенаправить в одну строку как:

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

Здесь std::cin.rdbuf(in.rdbuf())устанавливается std::cin'sбуфер, in.rdbuf()а затем возвращается старый буфер, связанный с std::cin. То же самое можно сделать с std::cout- или с любым потоком в этом отношении.

Надеюсь, это поможет.


4
Нужно ли мне закрывать файлы перед сбросом cin и cout на стандартный ввод-вывод?
апдоглю

3
@updogliu: Нет. Если хотите, вы можете использовать inи outдля чтения и записи, in.txtи out.txtсоответственно. Кроме того , файлы будут автоматически закрыты , когда inи outвыходят из области видимости.
Nawaz

Мне нравится это решение, freopenпотому что я больше не могу получить stdoutобратно, если использую freopen. stackoverflow.com/questions/26699524/…
xxks-kkk

88

Просто пиши

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

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

14
Это перенаправление stdout, а не cout.
апдоглю

5
Это также перенаправит printf, что в некоторых случаях может быть хорошо.
JDiMatteo

5
@AkshayLAradhya Не при установке std::sync_with_studio(false);, хотя по умолчанию установлено значение true.
vsoftco

2
@ PřemyslŠťastný почему?
регги-гитара

4
Если бы ответы были равны по функциональности, эквивалентом этого C ++ была бы ofstream out("out.txt"); cout.rdbuf(out.rdbuf());только одна дополнительная строка, и она переносима. Не ооочень проще :)
nevelis

19

Вот короткий фрагмент кода для отслеживания cin / cout, полезного для соревнований по программированию:

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

Это дает дополнительное преимущество, заключающееся в том, что простые потоки fstream работают быстрее, чем синхронизированные потоки stdio. Но это работает только для одной функции.

Глобальное перенаправление cin / cout можно записать как:

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

Обратите внимание, что ios_base::sync_with_stdioтакже сбрасывается std::cin.rdbuf. Так что порядок имеет значение.

См. Также значение ios_base :: sync_with_stdio (false); cin.tie (NULL);

Потоки std io также могут быть легко затенены для объема одного файла, что полезно для конкурентного программирования:

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

Но в этом случае мы должны выбирать stdобъявления одно за другим и избегать, using namespace std;поскольку это приведет к ошибке двусмысленности:

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
                   ^

См. Также Как правильно использовать пространства имен в C ++? , Почему "использование пространства имен std" считается плохой практикой? и как разрешить конфликт имен между пространством имен C ++ и глобальной функцией?


15

предполагая, что имя вашей программы компиляции - x.exe, а $ - системная оболочка или приглашение

$ x <infile >outfile 

принимает входные данные из файла и выводит его в выходной файл.


Это не связано с C ++ и дает сбой в любом нетривиальном примере, например, когда ваша программа порождает дочерние процессы, которые пишут в консоль. По крайней мере, с этой проблемой я столкнулся, когда попробовал такое перенаправление, поэтому я здесь.
ashrasmun

5

Попробуйте перенаправить cout в файл.

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

Читать статью полностью. Использование std :: rdbuf для перенаправления cin и cout


1
На этот вопрос был дан ответ почти 6 лет назад (в 2012 году), но вы добавили ответ сейчас, в 2018 году. Ваш ответ такой же, как принятый ответ. Так что я интересно , почему ты этот пост , когда не было ничего нового , чтобы добавить?
Наваз

В моем ответе специально выделена только версия cout, а подробный ответ дан по ссылке ниже.
HaseeB Mir

Что нового в вашем ответе, чего нет в принятом ответе?
Nawaz

2
Мой ответ не смешивает перенаправление как cout, так и cin, моя версия разделяется, чтобы сделать ее более читаемой
HaseeB Mir
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.