更改预定义流对象所连接的设备

时间:2012-07-12 04:52:48

标签: c++ stream

默认情况下,当包含标题的c ++应用程序时,将实例化以下4个流对象, cin,cout,cerr clog (对应的宽字符类型为也实例化了。)

现在默认 cin 连接到标准输入设备,通常是键盘, cout,cerr clog 连接到标准输出设备,通常是控制台。

我的问题是我们如何更改这些预定义的流对象所连接的设备?

3 个答案:

答案 0 :(得分:2)

你可以使用类似于这个的助手类:

class RedirectOutput
{
    std::ostream &os_;
    std::filebuf f_;
    std::streambuf *obuf_;
    RedirectOutput (const RedirectOutput &);  // disallow
    void operator = (const RedirectOutput &); // disallow
public:
    RedirectOutput (std::ostream &os,
                    std::string where,
                    std::ios::openmode mode = std::ios::out)
        : os_(os.flush()) {
        f_.open(where.c_str(), mode);
        obuf_ = os.rdbuf(&f_);
    }
    ~RedirectOutput () {
        os_.flush();
        os_.rdbuf(obuf_);
    }
};

并像这样使用它:

{
   RedirectOutput ro(std::cout, "output.txt");
   std::cout << "Hello" << std::endl;
}
std::cout << "Goodbye" << std::endl;

Hello转到文件output.txt,而Goodbye转到终端。

答案 1 :(得分:2)

是的,它是可能的,不,它不依赖于操作系统。这是一个快速演示,重定向cout以写入文件:

#include <iostream>
#include <fstream>

int main() { 
    // create a file buf, and open it on a file named "your_output.txt":
    std::basic_filebuf<char, std::char_traits<char> > b;
    b.open("your_output.txt", std::ios_base::out);

    // connect `std::cout` to the chosen file via our file_buf:
    std::cout.rdbuf(&b);

    // write some output (which shouldn't show up on screen.
    std::cout << "This is some junk";
    return 0;
}

请注意,作为一项规则,我建议不要这样做。通常更清晰(例如)将代码移动到一个函数中,该函数将ostream作为参数引用,然后根据需要传递适当的ostream或ofstream。另一方面,如果您(例如)有大量现有代码已经从/向编码的标准流进行读/写操作,这可以让它无需重写就能完成。

答案 2 :(得分:1)

这取决于操作系统,但在类Unix系统上,您无法在程序运行时执行此操作。您必须在启动流程时进行设置。

例如,如果您在zsh shell中以这种方式运行程序:

./myprogram < file1  > file2  2> file3

...然后cinfile1读取,cout写入file2cerr写入file3