Потоки печати и перенаправления - PullRequest
0 голосов
/ 19 августа 2011

У меня есть программа, которая печатает (с помощью printf) на stdout некоторые данные, а также вызывает функцию *foo* который также печатает в stdout некоторые данные [способ (реализация) того, как выполняется печать из foo , неизвестен, и я не могу увидеть код foo].

Я должен перенаправить все с stdout на buffer или файл. Я пытался сделать это несколькими способами

  1. freopen(file.txt, stdout) - в файл file.txt записываются только мои распечатки кода. То, что было напечатано с foo, потеряно.
  2. setbuf(buffer, stdout) - только мои распечатки кода записываются в буфер. То, что было напечатано из foo, появляется в stdout. (Появляется на экране)

Чем можно объяснить это поведение? Как решить проблему?

Примечание: этот код должен работать в кросс-ОС (lunux / wind && mac OS). Я использую gcc для компиляции кода, и у меня есть cygwin

Ответы [ 3 ]

2 голосов
/ 19 августа 2011

Вполне вероятно, что foo не использует stdio для печати и прямого вызова ОС для этого.

Я не знаю о win32, но в POSIX вы могли бы использовать dup2 чтобы позаботиться об этом.

/* Before the function foo is called, make `STDOUT_FILENO` refer to `fd` */
int fd;
fd = open(...);
dup2(fd, STDOUT_FILENO);

РЕДАКТИРОВАТЬ

К моему большому удивлению, win32 имеет _dup2, ноон делает что-то еще.

1 голос
/ 19 августа 2011

Откуда вы знаете, что foo() печатает на stdout? Вы пытались перенаправить стандартный вывод в файл оболочки и посмотреть, появляется ли на экране вывод из foo()?

Если перенаправление файла отправляет вывод foo() в файл, то вам, возможно, придется перенастроить уровень дескриптора файла, как в cnicutar .

Если перенаправление файла не отправляет вывод foo() в файл, то это может быть запись в stderr или открытие или использование /dev/tty или что-то подобное. Вы можете проверить на stderr, перенаправив его отдельно от stdout:

your_program >/tmp/stdout.me 2>/tmp/stderr.me

Если он открывается /dev/tty, вывод все равно будет отображаться на вашем экране.

На какой ты платформе? Если вы можете отслеживать системные вызовы (strace в Linux, truss в Solaris, ...), то вы сможете увидеть, что делает функция foo(). Вы можете помочь, написав сообщение до и после вызова функции и убедившись, что вы сбросили вывод:

printf("About to call foo()\n");
fflush(0);
foo();
printf("Returned from foo()\n");
fflush(0);

Вызовы printf / fflush будут видны в выводе трассировки, поэтому все, что появляется между ними, выполняется с помощью foo().

0 голосов
/ 19 августа 2011
Что может объяснить такое поведение?

Я видел такое поведение, когда код, в который вы вызываете, использует библиотеку C, отличную от вашей.В Windows я видел подобные вещи, когда одна DLL компилируется с GCC, а другая с Visual C ++.Реализация stdio для них, по-видимому, достаточно различна, так что это может быть проблематично.

Другое дело, что код, который вы вызываете, не использует stdio.Если вы работаете в Unix, вы можете использовать dup2, чтобы обойти это, например.dup2(my_file_descriptor, 1).Во многих реализациях, если у вас есть FILE*, вы можете сказать dup2(fileno(f), 1).Это не может быть переносимым.

...