使用 C++ 读取进程本身的标准输出

read stdout of a process in itself using c++

考虑我们有 some_function 并将结果打印到 stdout 而不是返回 it.Changing 它的定义超出了我们的范围并且没有其他选择。我们可以选择从 stdout 读取它。所以问题。

如何读取 C++ 程序本身的标准输出。

有可能获得 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 取决于调用的进程它因此我们想称它为进程本身而不是创建子进程。

How to read stdout of C++ program in itself?

这样做的理由很少,这通常(但不总是)是设计错误。

注意一件重要的事情(至少在 single-threaded 程序中)。如果您的程序既从其 "stdout" 中读取又(像往常一样)在其中写入,它可能会陷入死锁:无法读取,因此无法到达任何输出例程,(或无法写入,因为管道已满).

所以一个程序同时读取和写入相同的东西(实际上,相同的两侧pipe(7)) should use some multiplexing call like poll(2). See also this

一旦你明白了这一点,你就会有一些 event loop. And before that, you'll make a pipe(7) using pipe(2) (and dup2(2)).

然而,在某些 signal(7) handling (see signal-safety(7)). That trick is even recommended in Qt Unix signal handling.

中,pipe to self 是一件好事

阅读有关 Unix 系统编程的更多信息,例如ALP or some newer book. Read also intro(2) & syscalls(2).

I have looked for pipe and it requires fd

错了。仔细阅读pipe(2); on success it fills an array of two file descriptors. Of course it could fail (see errno(3) & perror(3) & strerror(3))

也许你只需要 popen(3). Or std::ostringstream. Or open_memstream(3).

Consider we have some_function and it prints result to stdout instead returning it. Changing it's definition is out of our scope and there's no alternative to it

如果 some_function 是您的代码,或者是一些 free software,您可以并且可能应该改进它以在某处给出结果....

这并不难,但在我看来这很麻烦,而且它不适用于多线程程序:

// 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

错误检查、正确 headers、将 C stdout 与 C++ cout 同步以及读取和清理临时文件留作练习...;-)

请注意,您不能安全地使用管道 - 函数可以写入足够多的内容来填满管道,并且您不能从管道中读取,因为您已经调用了函数。