0

默认情况下,当包含 header 的 c++ 应用程序时,会实例化以下 4 个流对象,cin、cout、cerrclog(也实例化相应的宽字符类型)。

现在默认情况下cin连接到通常是键盘的标准输入设备,而cout、cerrclog连接到通常是控制台的标准输出设备。

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

4

3 回答 3

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转到终端。

于 2012-07-12T05:24:13.863 回答
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,通常会更简洁(例如)。另一方面,如果您(例如)有一大块现有代码已经对标准流进行了读/写,那么这可以让它工作而无需全部重写。

于 2012-07-12T05:24:30.203 回答
1

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

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

./myprogram < file1  > file2  2> file3

...然后cin读取file1cout写入file2cerr写入file3

于 2012-07-12T04:56:19.580 回答