0

我读到freopen将所有内容重定向printf到一个文件,但我也希望将输出打印在屏幕上。有没有一种简单的方法可以将 printfs 重定向到文件并获取 cmd 行输出?

谢谢!

4

3 回答 3

1

另一种选择是编写一个类似 的函数printf,但将输出定向到两个不同的位置。例如:

#include <stdio.h>
#include <stdarg.h>

void printf2(FILE *fp, char *format, ...)
{
    va_list ap;
    va_list ap2;

    va_start(ap, format);
    va_copy(ap2, ap);

    vfprintf(fp, format, ap);
    va_end(ap);

    vprintf(format, ap2);
    va_end(ap2);
}

然后,您可以以与调用printf2相同的方式调用fprintf,并且输出将发送到传入的FILE指针和标准输出:

FILE *fp = fopen("/tmp/foo", "w");
printf2(fp, "This is a test.\n");

这种方法不使用子进程或管道,如有必要,它可以推广到多个文件指针。

于 2010-07-09T17:32:57.757 回答
0

在程序外部,使用“tee”:

# echo foo | tee foo.txt
foo
# cat foo.txt
foo

实际上,您可以将通道 popen() 连接到写入文件的 tee,尽管这对系统来说很繁重。有这样的效果:

FILE *stream_to_write_to = popen( "tee filename.txt" );
fprintf( stream_to_write_to, "goes to filename.txt and stdout\n" );

我很想知道是否有从-C 快速执行此操作的方法,因为在某种程度上,这涉及复制数据。很容易让两个文件句柄写入同一个地方,使用 dup() 或类似的方法,但相反的更棘手。它可能涉及推送一个模块(常见的例子是“connld”到一个流上),虽然老实说我从来没有见过这个,所以我很想自己看看一个工作代码示例。

我能给出的最佳参考是 Stevens 的“UNIX 环境中的高级编程”。

更新:

说到下面 R 的评论,上面的解决方案是一个稍微重一点的版本,只是 fork/exec-ing 并将孩子的句柄重定向到其他地方。两者都可以解决问题,虽然我更喜欢上面的方法,因为它更容易清理,但老实说,这两种解决方案都相当繁重。Fork() 不是轻量级函数。如果问题的精神是在没有 fork/exec 的情况下这样做,那么我不确定,我也很想知道。如果 fork/exec 没问题,那么直接使用它或使用 popen() 将破解它。

于 2010-07-09T16:51:25.937 回答
0

freopen重定向标准输出不是一个好主意。它不一定会重用相同的文件描述符编号,因此子进程可能不会继承新的标准输出(或者最终可能根本没有标准输出)。最好使用openthendup2close(0)thenopen为 stdout 创建一个新目标。

于 2010-07-09T16:59:02.347 回答