如何捕获 printf 的输出

How to capture output of printf?

本文关键字:输出 printf 何捕获      更新时间:2023-10-16

我正在调用funcA funcB函数。 funcB使用多个printf语句来输出数据。有没有办法让我通过funcA捕获这些数据?我无法修改funcB.

funcB(){
     printf( "%s", "My Name is" );
     printf( "%s", "I like ice cream" );
}
funcA(){
    funcB();
}

(此答案是基于此答案的更正版本。

这个答案是以POSIX为中心的。使用 open 为要重定向到的文件创建文件描述符。然后,使用 dup2 to STDOUT_FILENO 更改stdout以改为写入文件。但是,您需要在执行此操作之前dup STDOUT_FILENO,以便您可以使用其他dup2恢复stdout

fflush(stdout);
int stdout_fd = dup(STDOUT_FILENO);
int redir_fd = open(redirected_filename, O_WRONLY);
dup2(redir_fd, STDOUT_FILENO);
close(redir_fd);
funcB();
fflush(stdout);
dup2(stdout_fd, STDOUT_FILENO);
close(stdout_fd);

如果funcB使用的是std::cout,请使用std::cout.flush()而不是fflush(stdout)

如果你想更直接地操纵C++流,你可以使用Johnathan Wakely的答案。

如果您的程序中没有其他内容使用 printf ,您可以编写自己的版本并显式链接它。如果已定义函数,则链接器将不会在标准库中查找。您可能可以使用vsprintf来实现,或者使用一些更安全的版本进行溢出检查,如果它是由编译器提供的。

如果你愿意玩一个肮脏的游戏,你可以在printf上"窃取"它的输出,这样做如下:

#include <stdio.h>
#include <stdarg.h>
static char buffer[1024];
static char *next = buffer;
static void funcB(){
     printf( "%s", "My Name is" );
     printf( "%s", "I like ice cream" );
}
static void funcA(){
    funcB();
    // Do stuff iwth buffer here
    fprintf(stderr, "stole: %sn", buffer);
    next=buffer; // reset for later.
}
int main() {
  funcA();
}

int printf(const char *fmt, ...) {
   va_list argp;
   va_start(argp, fmt);
   const int ret = vsnprintf(next, sizeof buffer-(next-buffer), fmt, argp);
   next += ret;
   va_end(argp);
   return ret;
}

您可以使用标志来指示如何处理您希望 printf 正常工作的实例。(例如,将其映射到fprintf或使用dlsym()/similar来查找真正的呼叫)。

您还可以使用 realloc 更明智地管理缓冲区的大小。

funcB放在一个单独的程序中。然后,您可以捕获其标准输出,例如通过管道或将其重定向到文件。如何做到这一点通常取决于操作系统,并且超出了C++的范围。

或者,也许您可以将funcA进程的标准输出重定向到文件,然后调用 FuncB 并从文件中检索输出。

同样,如何做到这一点超出了C++的范围,取决于操作系统。