输出到文件和命令行

时间:2010-07-09 16:47:07

标签: c printf stdout freopen

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

谢谢!

3 个答案:

答案 0 :(得分: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指针和stdout:

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

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

答案 1 :(得分: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没问题,那么直接使用它或使用popen()就会破解它。

答案 2 :(得分:0)

freopen不是重定向stdout的好主意。它不一定会重复使用相同的文件描述符编号,因此子进程可能不会继承新的stdout(或者最终可能没有stdout)。最好使用open然后dup2close(0)然后open为stdout创建新目标。