2012-06-19 3 views
7

Я вызываю функцию funcB от funcA. funcB использует несколько операторов printf для вывода данных. Есть ли способ для захвата этих данных через funcA? Не могу изменить funcB.Как захватить вывод printf?

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

funcA(){ 
    funcB(); 
} 
+2

Что делать, если 'funcB' не выводит свой вывод, а возвращает его вместо' funcA'? Трудно сказать из абстрактного описания, как вы указали, быть более конкретным. – LihO

+2

* «Это вопрос на C++» * - это больше похоже на вопрос C для меня. Если бы это был C++, вы могли бы сделать что-то вроде: [this] (http://stackoverflow.com/a/8076948/168175). – Flexo

+0

Это больше похоже на OS-specfic вопрос для меня, о чем я упоминал в своем ответе. –

ответ

10

Этот ответ POSIX ориентирован. Вы можете использовать freopen для перенаправления stdout в файл. Но вам нужно будет dupSTDOUT_FILENO, прежде чем вы это сделаете, чтобы вы могли восстановить stdout в нечто похожее на его исходное состояние с 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); 

Для потоков C++, вы можете использовать Johnathan Wakely's answer.

+0

Вы управляете чуваком, это сработало! – Gene

0

Положить funcB в отдельную программу. Затем вы можете записать свой стандартный вывод, например. по трубопроводу или путем перенаправления его в файл. Как это сделать, как правило, зависит от ОС и находится за пределами C++.

В качестве альтернативы, возможно, вы можете перенаправить свой стандартный вывод процесса funcA в файл, а затем вызвать FuncB и получить выход из файла.

Опять же, как это сделать за пределами C++ и зависит от ОС.

1

Если ничего в вашей программе не используется printf, вы можете написать свою собственную версию и напрямую связать ее. Компонент не будет выглядеть в стандартной библиотеке, если функция уже определена. Вы, вероятно, можете использовать vsprintf для реализации или какую-то более безопасную версию с проверкой переполнения, если она предоставляется вашим компилятором.

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 для более разумного управления размером буфера.

Смежные вопросы