流打印和重定向

时间:2011-08-19 18:08:13

标签: c redirect printf stdout

我有一个程序可以打印(通过printf)stdout一些数据并调用函数*foo* 还打印到stdout一些数据[从 foo 打印的方式(实现)是未知的,我看不到foo的代码]。

我必须将所有内容从stdout重定向到buffer或文件。我尝试过几种方式

  1. freopen(file.txt, stdout) - 只有我的代码打印才会写入file.txt。从foo打印的内容丢失了。
  2. setbuf(buffer, stdout) - 只有我的代码打印才会被写入缓冲区。从foo打印的内容出现在标准输出中。(它出现在屏幕上)
  3. 有什么可以解释这种行为?怎样才能解决问题?

    注意:此代码必须在跨操作系统(lunux / wind&& mac OS)中工作。我使用gcc编译代码,我有cygwin

3 个答案:

答案 0 :(得分:2)

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 has _dup2 但它还有其他功能。

答案 1 :(得分:1)

您如何知道foo()正在打印到stdout?您是否尝试将标准输出重定向到shell中的文件,并查看foo()的输出是否仍显示在屏幕上?

如果文件重定向将foo()的输出发送到文件,那么您可能必须重新调整文件描述符级别,如cnicutar的答案。

如果文件重定向没有将foo()的输出发送到文件,那么它可能正在写入stderr,或者它可能正在打开并使用/dev/tty或类似的东西。您可以通过将stderr与<{1}}分开重定向来测试stdout

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

如果正在打开/dev/tty,输出仍会显示在屏幕上。

你在哪个平台上?如果您可以跟踪系统调用(Linux上的strace,Solaris上的truss,...),那么您可能会看到foo()函数正在执行的操作。您可以通过在调用函数之前和之后编写消息来帮助您,并确保您刷新输出:

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

printf / fflush调用将在跟踪输出中显示,因此显示的内容由foo()完成。

答案 2 :(得分:0)

什么可以解释这种行为?

当您调用的代码使用与您不同的C库时,我已经看到过这种行为。在Windows上,当使用GCC编译一个DLL而使用Visual C ++编译另一个DLL时,我常常看到这种情况。 stdio对这些的实施明显不同,这可能会产生问题。

另一个原因是您调用的代码未使用stdio。如果您在Unix上,可以使用dup2来解决这个问题,例如。 dup2(my_file_descriptor, 1)。在许多实现中,如果您有FILE*,则可以说dup2(fileno(f), 1)。这可能不便携。