2012-04-14 2 views
96

Как перенаправить cin на номер in.txt и cout на номер out.txt?Как перенаправить cin и cout в файлы?

+6

Перенаправление CIN в строку: http://stackoverflow.com/questions/4925150/redirect-cin-to-a-string - Перенаправление соиЬ в строку: HTTP: // StackOverflow.com/questions/1162068/redirect-both-cout-and-stdout-to-a-string-in-c-for-unit-testing –

ответ

159

Вот рабочий пример того, что вы хотите сделать. Прочитайте комментарии, чтобы узнать, что делает каждая строка в коде. Я тестировал его на своем компьютере с 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 в стандартный IO? – updogliu

+3

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

68

Просто напишите

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

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

Это перенаправление 'stdout', а не' cout'. – updogliu

+3

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

+1

@updogliu, насколько я знаю, stdout и cout все время синхронизируются –

12

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

$ x <infile >outfile 

будет принимать входной сигнал от INFILE и выводится выходной_файл.

8

Вот короткий фрагмент кода для затенения CIN/соиЬ полезно для соревнований по программированию:

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

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

Global CIN/соиЬ редирект можно записать в виде:

#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. Таким образом, порядок имеет значение.

Смотрите также Significance of ios_base::sync_with_stdio(false); cin.tie(NULL);

Std И.О. потоки также могут быть легко слежку за рамки одного файла, который является полезным для конкурентного программирования:

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

Смотрите также How do you properly use namespaces in C++?, Why is "using namespace std" considered bad practice? и How to resolve a name collision between a C++ namespace and a global function?