有没有办法将 stdout/stderr 重定向到字符串?
之前有很多关于将 stdout/stderr 重定向到文件的问题。有没有办法将 stdout/stderr 重定向到字符串?
there has been many previous questions about redirecting stdout/stderr to a file. is there a way to redirect stdout/stderr to a string?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
是的,您可以将其重定向到 std::stringstream:
您可以使用一个简单的保护类来确保缓冲区始终重置:
Yes, you can redirect it to an
std::stringstream
:You can use a simple guard class to make sure the buffer is always reset:
您可以使用此类:
在需要开始捕获时调用
BeginCapture()
当您需要停止捕获时调用
EndCapture()
调用
GetCapture()
检索捕获的输出You can use this class:
call
BeginCapture()
when you need to start capturecall
EndCapture()
when you need to stop capturecall
GetCapture()
to retrieve captured output为了提供线程安全&跨平台解决方案,我已将 rmflow 的方法改编为类似的界面。由于此类修改全局文件描述符,我将其改编为互斥锁保护的静态类,以防止多个实例对全局文件描述符造成影响。此外,rmflow 的答案不会清除所有已使用的文件描述符,如果许多 BeginCapture() 和文件描述符,这可能会导致打开新文件描述符(用于输出流或文件)时出现问题。 EndCapture() 调用在一个应用程序中使用。此代码已在 Windows 7/8、Linux、OSX、Android 和 iOS 上进行了测试。
注意:为了使用 std::mutex,您必须针对 c++ 11 进行编译。如果您不/不能使用 c++11,您可以完全删除互斥调用(牺牲线程安全),或者您可以找到遗留的同步机制来完成工作。
调用
Init()
一次(在捕获之前)以删除对 stdout / stderr 的缓冲在需要开始捕获时
调用
BeginCapture()
调用EndCapture()
当您需要停止捕获时,调用
GetCapture()
来检索捕获的输出,调用
IsCapturing()
来查看 stdout/stderr 当前是否已重定向In order to provide a thread-safe & cross platform solution, I have adapted rmflow's approach into a similar interface. As this class modifies global file descriptors, I adapted it to a mutex-guarded static class that protects against multiple instances thrashing global file descriptors. In addition, rmflow's answer does not clean up all of the used file descriptors which can lead to problems opening new ones (for output streams or files) if many BeginCapture() & EndCapture() calls are used in one application. This code has been tested on Windows 7/8, Linux, OSX, Android, and iOS.
NOTE: In order to use std::mutex you must compile against c++ 11. If you do not / cannot use c++11, you can remove the mutex calls completely (sacrificing thread safety) or you can find a legacy sychronization mechanism to get the job done.
call
Init()
once (before capture) to remove buffering to stdout / stderrcall
BeginCapture()
when you need to start capturecall
EndCapture()
when you need to stop capturecall
GetCapture()
to retrieve captured outputcall
IsCapturing()
to see if stdout/stderr is currently redirected我已经提供了 Björn Pollex 代码的 qt osx 就绪变体
i've furnished a qt osx ready variation from Björn Pollex code
我修改了
Sir Digby Chicken Caesar
中的类,使其不是静态的,并且可以在单元测试中轻松使用。它在 gcc (g++) 编译的 Windows 上适用于我,但我不能保证它是 100% 正确的,如果不是,请留下评论。创建 StdCapture 类的对象,然后调用
BeginCapture()
开始捕获,并在结束时调用EndCapture()
。Init()
中的代码被移至构造函数。一次只能有一个这样的对象在工作。StdCapture.h:
StdCapture.cpp:
I modified class from
Sir Digby Chicken Caesar
so that it's not static and could be used easily in unit tests. It works for me on Windows compiled by gcc (g++), but I cannot guarantee that it is 100% correct, please leave comments if it is not.Create object of class StdCapture, and just call
BeginCapture()
to begin capture andEndCapture()
at the end. Code fromInit()
is moved to the constructor. There shall be only one such object working at a time.StdCapture.h:
StdCapture.cpp:
由于您的问题被标记为 C 和 C++,因此似乎应该提到,尽管您无法将字符串与标准 C 中的 FILE * 关联起来,但有几个非标准库允许这样做。 glibc 几乎是标准的,因此您可能会非常高兴使用 fmemopen() 请参阅 http://www.gnu.org/s/libc/manual/html_mono/libc.html#String-Streams
Since your question is tagged C as well as C++, it seems appropriate to mention that although you cannot associate a string to a FILE * in standard C, there are several non-standard libraries that allow that. glibc is almost standard, so you may be perfectly happy using fmemopen() See http://www.gnu.org/s/libc/manual/html_mono/libc.html#String-Streams