将 cout 和 stdout 都重定向到 C++ 中的字符串以进行单元测试

Posted

技术标签:

【中文标题】将 cout 和 stdout 都重定向到 C++ 中的字符串以进行单元测试【英文标题】:Redirect both cout and stdout to a string in C++ for Unit Testing 【发布时间】:2009-07-21 22:23:38 【问题描述】:

我正致力于在单元测试中获取一些遗留代码,有时感知现有程序行为的唯一方法是从控制台输出。

我在网上看到很多关于如何将标准输出重定向到 C++ 中的另一个文件的示例,但是有没有办法可以将它重定向到内存中的流,这样我的测试就不必依赖磁盘了?

我想将遗留代码发送到 stdout 的任何内容放入 std::string 中,以便我可以轻松地在输出中找到。

编辑

遗留代码非常糟糕,它使用了cout << ..printf 的混合体。这是我目前所拥有的:

void TestSuite::setUp(void)

    oldStdoutBuf = std::cout.rdbuf();
    std::cout.rdbuf(consoleOutput.rdbuf());

void TestSuite::tearDown(void)

    std::cout.rdbuf(oldStdoutBuf);

问题在于,这使用 printf 捕获输出。我想要两者兼得的东西。有什么想法吗?

【问题讨论】:

下面的答案都对我有用,你有这个工作的例子吗? 【参考方案1】:

std::stringstream 可能就是您要找的。​​p>

更新 好吧,这有点小技巧,但也许你可以这样做来获取 printf 输出:

char huge_string_buf[MASSIVE_SIZE];
freopen("NUL", "a", stdout);
setbuf(stdout, huge_string_buffer);

请注意,对于 linux,您应该使用“/dev/null”而不是“NUL”。这将迅速开始填满 huge_string_buffer。如果希望在缓冲区满后继续重定向输出,则必须调用 fflush(),否则会抛出错误。请参阅std::setbuf 了解更多信息。

【讨论】:

接受了你的回答,因为 stringstream 是一个很好的指针,你的 UPDATE 大约是我们可能会得到的,而不需要写一些非常复杂的混乱,现在我想我只是写一个文件,希望很多测试我都不需要 printf 输出。 效果很好,但是如果我使用多个单元测试,有些失败并出现异常,因为缓冲区已被释放并且标准输出已写入其中。如果只是临时重定向到缓冲区,请在使用结束时使用setbuf(stdout, NULL); 查看此答案以避免 POSIX 系统上的“NUL”-Hack:***.com/a/19499003/1557062【参考方案2】:

您可以使用freopen(..., stdout),然后将文件转储到内存或std::string

【讨论】:

我真的很想跳过必须使用文件系统。最好只使用 ram 的东西。【参考方案3】:

这可能是另一种选择:

char bigOutBuf[8192];
char savBuf[8192];

fflush(stdout);
setvbuf(stdout,bigOutBuf,IOFBF,8192);//stdout uses your buffer

//after each operation
strncpy(savBuf,bigOutBuf,8192);//won't flush until full or fflush called

//...

//at long last finished
setbuf(stdout,NULL);//reset to unnamed buffer

这只是截取缓冲的输出,所以仍然会转到控制台或任何地方。

希望这会有所帮助。

【讨论】:

我想完全抑制控制台输出,只保留捕获的缓冲区可以吗?【参考方案4】:

试试 sprintf,效率更高。

int i;
char str[] = "asdf";
char output[256];
sprintf(output, "asdfasdf %s %d\n", str, i);

【讨论】:

以上是关于将 cout 和 stdout 都重定向到 C++ 中的字符串以进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

linux将标准输出和标准错误输出都重定向到一个文件?

搞懂 fflush(stdout)

C++代码调试的学习笔记

我所有的 WordPress 页面都重定向到 Xampp 的主页

可以将 std::cout 重定向到开箱即用的 Visual Studio 2010 C++ 中的输出视图吗?

nginx中实现把所有http的请求都重定向到https