如何捕获printf的输出?

时间:2012-06-19 22:17:17

标签: c++ printf

我从funcB调用了一个函数funcAfuncB使用多个printf语句来输出数据。 我有办法通过funcA捕获这些数据吗? 我无法修改funcB

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

funcA(){
    funcB();
}

4 个答案:

答案 0 :(得分:12)

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

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

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's answer

答案 1 :(得分:1)

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

答案 2 :(得分:1)

如果你愿意在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: %s\n", 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() /类似找到真正的电话)。

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

答案 3 :(得分:0)

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

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

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