默认情况下,当包含 header 的 c++ 应用程序时,会实例化以下 4 个流对象,cin、cout、cerr和clog(也实例化相应的宽字符类型)。
现在默认情况下cin连接到通常是键盘的标准输入设备,而cout、cerr和clog连接到通常是控制台的标准输出设备。
我的问题是我们如何更改这些预定义的流对象连接到的设备?
您可以使用与此类似的辅助类:
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
转到终端。
是的,这是可能的,不,它不依赖于操作系统。这是一个快速演示,重定向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,通常会更简洁(例如)。另一方面,如果您(例如)有一大块现有代码已经对标准流进行了读/写,那么这可以让它工作而无需全部重写。
这取决于操作系统,但在类 Unix 系统上,您不能在程序运行时执行此操作。您必须在启动该过程时进行设置。
例如,如果您在zsh
shell 中以这种方式运行程序:
./myprogram < file1 > file2 2> file3
...然后cin
读取file1
、cout
写入file2
和cerr
写入file3
。