在我的应用程序中,我想将通常转到stdout流的输出重定向到我定义的函数.我读到你可以将stdio重定向到一个文件,为什么不用一个函数呢?
例如:
void MyHandler( const char* data );
//<<Magical redirection code>>
printf( "test" );
std::cout << "test" << std::endl;
//MyHandler should have been called with "test" twice, at this point
Run Code Online (Sandbox Code Playgroud)
zpa*_*ack 42
@Konrad Rudolph是对的,你可以轻松完成这项工作,至少对于cout/cerr/clog来说.您甚至不需要自己的streambuf实现,只需使用ostringstream即可.
// Redirect cout.
streambuf* oldCoutStreamBuf = cout.rdbuf();
ostringstream strCout;
cout.rdbuf( strCout.rdbuf() );
// This goes to the string stream.
cout << "Hello, World!" << endl;
// Restore old cout.
cout.rdbuf( oldCoutStreamBuf );
// Will output our Hello World! from above.
cout << strCout.str();
Run Code Online (Sandbox Code Playgroud)
同样的事情适用于cerr和clog,但根据我的经验,一般不适用于stdout/stderr,因此printf不会输出.cout转到stdout,但重定向cout不会重定向所有stdout.至少,那是我的经历.
如果数据量预计很小,则freopen/setbuf工作正常.我最终做了更好的dup/dup2重定向到管道.
更新:我写了一篇博文,展示了我最终使用的dup2方法,你可以在这里阅读.它是为OS X编写的,但可能适用于其他Unix版本.我非常怀疑它在Windows中是否可行.Cocoa版同样在这里.
所有其他答案都是错误的.您可以这样做,并且您不需要求助于freopen任何其他C或非标准功能.
相反,您需要创建自己的std::streambuf实现,即您自己的流缓冲区.
完成后,您可以cout通过切换缓冲区来重定向流:
your_stream_buffer new_buffer;
streambuf* old_buffer = cout.rdbuf(&new_buffer);
cout << "Hello"; // This will be redirected to `new_buffer`.
// Restore original buffer:
cout.rdbuf(old_buffer);
Run Code Online (Sandbox Code Playgroud)
由于我自己从未这样做过,所以我无法准确地告诉你实现的效果如何streambuf.我的建议是查看文档并执行一个虚拟实现,为所有已实现的函数打印诊断.这应该有助于弄清楚班级的运作方式.
或者,查看一下您所选择的C++参考书来描述streambuf该类.
小智 5
可以通过取消引用其指针来禁用stdin/stdout:
FILE fp_old = *stdout; // preserve the original stdout
*stdout = *fopen("/dev/null","w"); // redirect stdout to null
HObject m_ObjPOS = NewLibraryObject(); // call some library which prints unwanted stdout
*stdout=fp_old; // restore stdout
Run Code Online (Sandbox Code Playgroud)
Foo*_*Bah -1
您可以使用 sprintf 写入字符数组,然后读取值:
char buf[1024];
sprintf(buf, "test");
MyHandler(buf);
Run Code Online (Sandbox Code Playgroud)
还有 snprintf 和其他一些取决于平台
| 归档时间: |
|
| 查看次数: |
46181 次 |
| 最近记录: |