输出到文件和命令行

发布于 2024-09-09 00:38:38 字数 124 浏览 4 评论 0原文

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

谢谢!

I read about freopen to redirect all printf to a file, but I would like the output to be printed on the screen as well. Is there an easy way to redirect the printfs to a file and get the cmd line output?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

神也荒唐 2024-09-16 00:38:38

另一种选择是编写一个类似于 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);
}

然后您可以像调用 fprintf 一样调用 printf2,并且输出将转到传入的 FILE指针和标准输出:

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

此方法不使用子进程或管道,并且如果需要,可以将其推广到多个文件指针。

Another alternative is to write a function that works like printf, but directs the output to two different places. For instance:

#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);
}

You can then call printf2 the same way you'd call fprintf, and the output will go to both the passed-in FILE pointer and to stdout:

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

This approach does not use subprocesses or pipes, and it can be generalized to multiple file pointers, if necessary.

塔塔猫 2024-09-16 00:38:38

从程序外部,使用“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() 就会破解它。

From outside the program, use "tee":

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

In fact, you could popen() a channel to a tee that writes the file, though that's system-heavy. Something to this effect:

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

I'm curious to see if there's a from-C quick way of doing this, because at some level, this involves copying data. It's easy to get two filehandles to write to the same place, use dup() or the like, but the opposite is more tricky. It might involve pushing a module (the common example is "connld" onto a stream), though honestly I've never seen this used, so I'd love to see a working code sample myself.

Best reference I can give is "Advanced Programming in the UNIX Environment" by Stevens.

Update:

To speak to R's comment below, the above solution is a slightly heavier version of just fork/exec-ing and redirecting the child's handle someplace else. Both will solve the problem, though I prefer the above because it's easier to clean up, but honestly, both solutions are pretty heavy. Fork() is no lightweight function. If the spirit of the question is to do so without fork/exec, then I'm not sure, I'd love to know, too. If fork/exec is okay, then directly using it or using popen() will hack it.

允世 2024-09-16 00:38:38

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

freopen is not a good idea for redirecting stdout. It will not necessarily reuse the same file descriptor number so child processes may not inherit the new stdout (or may end up with no stdout at all). It's better to use open and then dup2 or close(0) then open to create a new target for stdout.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文