2012-06-19 9 views
7

Llamo a una función funcB de funcA. funcB usa varias declaraciones printf para generar datos. ¿Hay alguna forma de capturar esos datos a través del funcA? No puedo modificar funcB.Cómo capturar la salida de printf?

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

funcA(){ 
    funcB(); 
} 
+2

¿Qué pasaría si 'funcB' no imprimiera su salida, pero en su lugar devuélvala a' funcA'? Difícil de decir a partir de la descripción del resumen que proporcionó, sea más específico. – LihO

+2

* "Esta es una pregunta en C++" * - se parece más a una pregunta en C para mí. Si fuera C++, podría hacer algo como: [this] (http://stackoverflow.com/a/8076948/168175). – Flexo

+0

Parece más una pregunta específica de sistema operativo para mí, como se alude en mi respuesta. –

Respuesta

10

Esta respuesta es POSIX céntrica. Puede usar freopen para redirigir stdout a un archivo. Pero, querrá dupSTDOUT_FILENO antes de hacerlo, para que pueda restaurar stdout a algo similar a su estado original con fdopen.

int stdout_fd = dup(STDOUT_FILENO); 
freopen(redirected_filename, "w", stdout); 
funcB(); 
fclose(stdout); 
dup2(stdout_fd, STDOUT_FILENO); 
stdout = fdopen(STDOUT_FILENO, "w"); 
close(stdout_fd); 

Para flujos de C++, puede utilizar Johnathan Wakely's answer.

+0

Tu mandas amigo, funcionó! – Gene

0

Ponga funcB en un programa separado. Luego puede capturar su salida estándar, p. por tuberías o por redirigirlo a un archivo. Cómo hacerlo generalmente depende del sistema operativo y está fuera del ámbito de C++.

O bien, puede redireccionar la salida estándar del proceso funcA a un archivo, luego llamar al FuncB y recuperar el resultado del archivo.

Una vez más, cómo hacerlo está fuera del ámbito de C++ y depende del sistema operativo.

1

Si nada más en su programa usa printf, puede escribir su propia versión y vincularla explícitamente. El vinculador no se verá en la biblioteca estándar si la función ya está definida. Probablemente pueda usar vsprintf para la implementación, o alguna versión más segura con verificación de desbordamiento si es suministrada por su compilador.

1

Si usted está dispuesto a jugar un juego sucio en la interposición de printf puede 'robar' hacer algo como su salida:

#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; 
} 

Se puede usar una bandera para indicar cómo manejar los casos en los que desee printf para trabajar de forma normal. (Por ejemplo, asócielo en fprintf o use dlsym()/similar para encontrar la llamada real).

También puede usar realloc para administrar el tamaño del búfer de manera más sensata.

Cuestiones relacionadas