I'm writing a unit test and therefore, cannot change the code within the file that I'm testing. The code that I'm testing has messages in cout that I am trying to redirect into a file to check to make sure that the program is outputting the right messages. Does anyone have a way to redirect stdout in another program that won't cause a lag? I have tried freopen() and that causes my program to hang for some reason.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
You could create a filebuf
then replace cout
's streambuf with it:
{
std::filebuf f;
f.open("output.txt", std::ios::out);
std::streambuf* o = std::cout.rdbuf(&f);
std::cout << "hello" << std::endl; // endl will flush the stream
std::cout.rdbuf(o);
}
You need to restore cout
's original streambuf again (or set it to a null pointer) or it will probably crash when the global streams are flushed and destroyed, because the filebuf
will already have gone out of scope.
回答2:
You can use 'open()' and 'dup2()'. You can use the helpers provided below. An example of how to use them:
void
code_to_test ()
{
std::cout << "Here we go" << std::endl;
std::cerr << "Danger danger" << std::endl;
}
run_test(code_to_test);
The run_test
helper invokes redirection, and runs the test code.
template <typename TEST> void
run_test (TEST t, bool append = false) {
flush_output();
Redirect o(1, "/tmp/test_stdout", append);
Redirect e(2, "/tmp/test_stderr", append);
t();
flush_output();
}
The flush_output
helper flushes the streams.
void flush_output () {
fflush(stdout);
fflush(stderr);
std::cout.flush();
std::cerr.flush();
}
The Redirect
class effects the redirection in the constructor. It restores the original descriptors back in the destructor.
class Redirect
{
int m_what;
int m_old_what;
public:
Redirect (int what, std::string where, bool append = false)
: m_what(what), m_old_what(dup(what)) {
int flags = O_CREAT|O_WRONLY;
if (append) flags |= O_APPEND;
int f = open(where.c_str(), flags, 0660);
dup2(f, m_what);
close(f);
}
~Redirect () {
dup2(m_old_what, m_what);
close(m_old_what);
}
};