cinとcoutをファイルにリダイレクトする方法は?


回答:


219

ここにあなたがしたいことの実際の例があります。コメントを読んで、コードの各行の機能を確認してください。PCで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
}

次のように、1行で保存してリダイレクトできます

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 2012

3
@updogliu:いいえ。必要に応じて、inおよびoutを使用してin.txtout.txtそれぞれ読み取りおよび書き込みを行うことができます。また、ファイルは自動的に閉じられますinし、out範囲を出て行きます。
Nawaz 2012

私はを使用するとfreopenもう取り戻すことができないので、私はこのソリューションよりもこのソリューションが好きです。stackoverflow.com/questions/26699524/...stdoutfreopen
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です。
updogliu 14

5
これにより、printfもリダイレクトされます。これは、場合によっては良いことです。
JDiMatteo 2015

5
@AkshayLAradhya std::sync_with_studio(false);デフォルトではに設定されていますが、設定した場合はそうではありませんtrue
vsoftco 2016年

2
@PřemyslŠťastnýなぜ?
レゲエギター2017

4
答えが機能的に同等である場合、これに相当するC ++はofstream out("out.txt"); cout.rdbuf(out.rdbuf());-余分な1行のみで、移植可能です。それほど単純ではありません:)
nevelis 2017

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宣言を1つずつ選択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 

infileから入力を受け取り、outfileに出力します。


これはC ++関連ではなく、たとえば、プログラムがコンソールに書き込む子プロセスを生成する場合など、重要な例では失敗します。少なくともそれが私がそのようなリダイレクトを試みたときに遭遇した問題であり、それゆえ私がここにいる理由です。
アシュラムン

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年に回答を追加しました。あなたの回答は承認された回答と同じです。あなたが持っていなかったとき、私は思ったんだけど、なぜあなたはこれを投稿しましたので、何も 新しい追加するの?
Nawaz

私の回答では、coutバージョンのみを特別に強調しています。詳細な回答は、以下のリンクにあります。
HaseeB Mir

受け入れられた回答にない、あなたの回答の新しいことは何ですか?
Nawaz

2
私の答えは、coutとcinの両方のリダイレクトを混合していません。私のバージョンは、読みやすくするために分離しています
HaseeB Mir
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.