我有一个程序可以打印(通过printf)stdout
一些数据并调用函数*foo*
还打印到stdout
一些数据[从 foo 打印的方式(实现)是未知的,我看不到foo的代码]。
我必须将所有内容从stdout
重定向到buffer
或文件。我尝试过几种方式
freopen(file.txt, stdout)
- 只有我的代码打印才会写入file.txt。从foo打印的内容丢失了。setbuf(buffer, stdout)
- 只有我的代码打印才会被写入缓冲区。从foo打印的内容出现在标准输出中。(它出现在屏幕上)有什么可以解释这种行为?怎样才能解决问题?
注意:此代码必须在跨操作系统(lunux / wind&& mac OS)中工作。我使用gcc编译代码,我有cygwin
答案 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)
。这可能不便携。