将 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++ 中的字符串以进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章
我所有的 WordPress 页面都重定向到 Xampp 的主页