Reputation: 661
I am calling a function funcB
from funcA
.
funcB
uses several printf
statements to output data.
Is there a way for me to capture that data via funcA
?
I can not modify funcB
.
funcB(){
printf( "%s", "My Name is" );
printf( "%s", "I like ice cream" );
}
funcA(){
funcB();
}
Upvotes: 9
Views: 14461
Reputation: 70392
(This answer is a corrected version based on this answer.)
This answer is POSIX centric. Use open
to create a file descriptor for the file you want to redirect to. Then, use dup2
to STDOUT_FILENO
to change stdout
to write to the file instead. But, you'll want to dup
the STDOUT_FILENO
before you do that, so you can restore stdout
with another 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);
If funcB
is using std::cout
, use std::cout.flush()
instead of fflush(stdout)
.
If you want to manipulate C++ streams more directly, you can use Johnathan Wakely's answer.
Upvotes: 15
Reputation: 88711
If you're willing to play a dirty game interposing on printf
you can 'steal' its output doing something like:
#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. (E.g. map it onto fprintf
or use dlsym()
/similar to find the real call).
You could also use realloc
to manage the size of the buffer more sensibly.
Upvotes: 1
Reputation: 308130
If nothing else in your program uses printf
, you can write your own version and link it explicitly. 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.
Upvotes: 2
Reputation: 145239
Put funcB
in a separate program. You can then capture its standard output, e.g. 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++.
Alternatively, maybe you can redirect your funcA
process' standard output to a file, then call FuncB
, and retrieve the output from the file.
Again, how to do that is outside the realm of C++ and depends on the OS.
Upvotes: 0