2016-06-11 4 views
1

Я хочу перенаправить stdout и stderr в функцию и написать простой код. fprintf в порядке, но когда я использую printf без \ r, поток переходит к терминалу!redirect stdout/stderr для функции в C

#include <stdio.h> 
static ssize_t file_write(void *c, const char *buf, size_t size) 
{ 
    FILE * pFile; 
    pFile = fopen ("output.txt","w"); 
    fprintf(pFile, "%s", buf); 
    fclose (pFile); 

return size; 
} 

void redirect() 
{ 
    FILE *stream; 
    stream=fopencookie(NULL, "w", (cookie_io_functions_t) {(ssize_t) 0, file_write, 0, 0}); 
    setbuf(stdout, NULL); 
    stdout = stream; 
    setbuf(stderr, NULL); 
    stderr = stream; 
} 

int main() 
{ 
    redirect(); 
    fprintf(stderr,"1-stderr test\n"); 
    fprintf(stdout, "2-stdout test\n"); 
    printf("3-printf with r test\n\r"); 
    printf("4-printf without r test\n"); 

return 0; 
} 

файл "output.txt":

1-STDERR тест
2-STDOUT тест
3-Printf с испытанием г

терминальный выход:

$ ./sample
4-Printf без г теста

+1

1. Отсоедините отступ 2. Почему бы не проверить возвращаемое значение из 'fopen' 3.' fprintf (pFile, buf); '- позволяет надеяться, что' buf' не содержит '%' в нем! –

+1

Вы используете 'buf' как строку формата. Это будет ужасно неудачно, если оно содержит любые '%' символы. Или используйте 'fprintf (pFile,"% s ", buf)' или иначе вызывать 'fwrite' вместо' fprintf'. –

+0

Вы также можете вызвать 'fputs' вместо' fprintf'. Это может быть проще всего. –

ответ

1

Вы не можете «перенаправить» стандартный ввод из или стандартный вывод функции в вашей программе.

Вы можете создать пару трубок и заменить стандартные входные и выходные данные этими трубами, а другую функцию (возможно, в другом потоке или даже дочернем процессе) использовать другой конец труб для связи с этой функцией.

Вы можете, конечно, использовать, например. setvbuf, чтобы изменить буферы stdin и stdout на пару буферов, которые вы предоставляете, затем вы можете напрямую читать или записывать непосредственно в буферы, как и любой другой буфер памяти (т. Е. Массив). Не то, чтобы я рекомендовал его, но он хрупкий и склонный к ошибкам.

Однако в этом случае кажется, что вы хотите, чтобы все записи в stdout должны были идти в файл. В этом случае (например, использование труб) нет стандартного способа его обработки, но вам необходимо использовать функциональные возможности операционной системы. Затем, если вы находитесь на платформе POSIX (например, Linux или OSX), вы можете сообщить операционной системе о дублировании базового файлового дескриптора для вашего файла и сказать, что STDOUT_FILNO (который является файловым дескриптором, используемым для stdout), является дубликатом для файловый дескриптор файла, который вы открыли. Затем все записи в stdout будут записаны в ваш файл. Для этого вам необходимо использовать the dup2 system call.

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