如何将cin和cout重定向到文件?


Answers:


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
}

您可以仅在一行中保存重定向为:

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:否。如果你愿意,你可以使用inout读取和写入操作,in.txtout.txt分别。此外,当超出范围时in,文件将自动关闭out
纳瓦兹

我喜欢这种解决方案,freopen因为stdout如果使用,我将再也无法获得回报freopenstackoverflow.com/questions/26699524/...
xxks,三K党

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 2014年

5
这也将重定向printf,在某些情况下这可能是一件好事。
JDiMatteo 2015年

5
@AkshayLAradhya设置时不设置std::sync_with_studio(false);,尽管默认情况下设置为true
vsoftco '16

2
@PřemyslŠťastný为什么?
reggaeguitar

4
如果答案在功能上相同,则C ++的等效形式将是ofstream out("out.txt"); cout.rdbuf(out.rdbuf());-仅需多一行,并且可移植。没那么简单:)
nevelis '17

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 

将从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年添加了一个答案。您的答案与已接受的答案相同。因此,我想知道为什么在没有要添加的内容的情况下 发布此帖子?
Nawaz

我的答案仅特别突出显示版本,详细答案在下面的链接中提供。
HaseeB Mir

您的答案中有什么新内容,而不是已接受的答案中有什么?
Nawaz

2
我的答案没有同时包含cout和cin的重定向,我的版本分开了以使其更具可读性
HaseeB Mir
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.