考虑我们有some_function
,它会将结果打印到stdout
而不是返回它。更改它的定义超出了我们的范围,除此之外别无选择。我们可以选择从stdout
阅读。所以问题。
如何阅读C ++程序的stdout本身。
如果我们可以获得相同程序的pid
但我无法找到任何内容,则可以fd
我搜索。
#include <unistd.h>
#include <sys/types.h>
#include <iostream>
void some_function(){
std::cout<<"Hello World";
}
int main(){
int pid = ::getpid();
string s = //What to write here.
cout<<"Printing";
some_function(); //This function prints "Hello World" to screen
cout<<s; //"PrintingHello World"
return 0;
}
如何将管道连接到同一个进程,而不是创建子进程。
有些人可能会考虑创建子流程并在其中调用some_function
,以便能够在父流程中读取其stdout
,但不,some_function
取决于调用它的流程和因此,我们希望将其称为过程,而不是创建子过程。
答案 0 :(得分:2)
如何阅读C ++程序的stdout本身?
这样做的理由很少,而通常是(但并不总是)设计错误。
注意一件重要的事情(至少在单线程程序中)。如果你的程序都是从&#34; stdout&#34;并且(像往常一样)写入它,它可能陷入死锁:无法读取因此无法达到任何输出例程,(或因管道已满而无法写入)。
因此,读取和写入相同内容(实际上,同一pipe(7)的两边)的程序应该使用一些多路复用调用,如poll(2)。另请参阅this。
一旦你理解了这一点,你就会有一些event loop。在此之前,您将使用pipe(7)(和pipe(2))制作dup2(2)。
然而,在某些signal(7)处理中管道自我是一件好事(参见signal-safety(7))。Qt Unix signal handling甚至建议使用这个技巧。
阅读有关Unix系统编程的更多信息,例如ALP或一些较新的书。另请阅读intro(2)&amp; syscalls(2)
我找了管道,它需要fd
错误。仔细阅读pipe(2);成功时,填充两个file descriptors的数组。当然可能会失败(见errno(3)&amp; perror(3)&amp; strerror(3))
也许你只需要popen(3)。或std::ostringstream
。或open_memstream(3)。
考虑我们有some_function并将结果打印到stdout而不是返回它。改变它的定义超出了我们的范围,除此之外别无选择
如果some_function
是您的代码,或者是某些free software,您可以并且可能应该对其进行改进以在某处提供结果....
答案 1 :(得分:2)
这并不难做到,但是IMO非常糟糕,并且它不会使用多线程程序:
// make a temp file to store the function's stdout
int newStdOut = mkstemp( "/tmp/stdout.XXXXXXX" );
// save the original stdout
int tmpStdOut = dup( STDOUT_FILENO );
// clear stdout
fflush( stdout );
// now point the stdout file descriptor to the file
dup2( newStdOut, STDOUT_FILENO );
// call the function we want to collect the stdout from
some_function();
// make sure stdout is empty
fflush( stdout );
// restore original stdout
dup2( tmpStdOut, STDOUT_FILENO );
// the tmp file now contains whatever some_function() wrote to stdout
检查错误,使用正确的标头,使用C ++ stdout
同步C cout
,并将读取和清理临时文件留作练习...; - )
请注意,您无法安全地使用管道 - 该功能可以写入足以填满管道,并且您无法从管道中读取,因为您已经调用了该功能。