[英]How to capture output of printf?
I am calling a function funcB
from funcA
. 我打电话的功能
funcB
从funcA
。 funcB
uses several printf
statements to output data. funcB
使用几个printf
语句来输出数据。 Is there a way for me to capture that data via funcA
? 有没有办法通过
funcA
捕获数据? I can not modify funcB
. 我无法修改
funcB
。
funcB(){
printf( "%s", "My Name is" );
printf( "%s", "I like ice cream" );
}
funcA(){
funcB();
}
(This answer is a corrected version based on this answer .) (这个答案是基于这个答案的更正版本。)
This answer is POSIX centric. 这个答案是以POSIX为中心的。 Use
open
to create a file descriptor for the file you want to redirect to. 使用
open
为要重定向到的文件创建文件描述符。 Then, use dup2
to STDOUT_FILENO
to change stdout
to write to the file instead. 然后,使用
dup2
到STDOUT_FILENO
来改变stdout
以写入文件。 But, you'll want to dup
the STDOUT_FILENO
before you do that, so you can restore stdout
with another dup2
. 但是,在执行此操作之前,您需要
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);
If funcB
is using std::cout
, use std::cout.flush()
instead of fflush(stdout)
. 如果
funcB
使用std::cout
,则使用std::cout.flush()
而不是fflush(stdout)
。
If you want to manipulate C++ streams more directly, you can use Johnathan Wakely's answer . 如果您想更直接地操作C ++流,可以使用Johnathan Wakely的答案 。
If nothing else in your program uses printf
, you can write your own version and link it explicitly. 如果您的程序中没有其他内容使用
printf
,您可以编写自己的版本并明确链接它。 The linker will not look in the standard library if the function is already defined. 如果已定义该函数,则链接器将不会查找标准库。 You can probably use
vsprintf
for the implementation, or some safer version with overrun checking if it is supplied by your compiler. 您可以使用
vsprintf
进行实现,或者使用溢出检查的某些更安全的版本(如果它是由编译器提供的)。
If you're willing to play a dirty game interposing on printf
you can 'steal' its output doing something like: 如果你愿意在
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;
}
You could use a flag to indicate how to handle the instances where you want printf to work as normal. 您可以使用标志来指示如何处理您希望printf正常工作的实例。 (Eg map it onto
fprintf
or use dlsym()
/similar to find the real call). (例如将其映射到
fprintf
或使用dlsym()
/类似于查找真实调用)。
You could also use realloc
to manage the size of the buffer more sensibly. 您还可以使用
realloc
更明智地管理缓冲区的大小。
Put funcB
in a separate program. 将
funcB
放在一个单独的程序中。 You can then capture its standard output, eg by piping or by redirecting it to a file. 然后,您可以捕获其标准输出,例如通过管道或将其重定向到文件。 How to do that generally depends on the OS and is outside the realm of C++.
如何做到这一般取决于操作系统,并且超出了C ++的范围。
Alternatively, maybe you can redirect your funcA
process' standard output to a file, then call FuncB
, and retrieve the output from the file. 或者,您可以将
funcA
进程的标准输出重定向到文件,然后调用FuncB
,并从文件中检索输出。
Again, how to do that is outside the realm of C++ and depends on the OS. 同样,如何做到这一点超出了C ++的范围,并取决于操作系统。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.