[英]Output into file and command line
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. 我读到有关freopen
,该文章将所有printf
重定向到文件,但是我也希望将输出也打印在屏幕上。 Is there an easy way to redirect the printfs to a file and get the cmd line output? 有没有一种简单的方法可以将printfs重定向到文件并获取cmd行输出?
Thanks! 谢谢!
Another alternative is to write a function that works like printf
, but directs the output to two different places. 另一种选择是编写一个功能类似于printf
,但是将输出定向到两个不同的位置。 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: 然后,您可以printf2
调用fprintf
一样调用printf2
,输出将同时传递到传入的FILE
指针和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. 这种方法不使用子进程或管道,并且可以根据需要将其通用化为多个文件指针。
From outside the program, use "tee": 在程序外部,使用“ 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. 实际上,您可以将通道popen()到可写入文件的tee上,尽管这很累。 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. 我很好奇,看看是否有一种from-C的快速方法,因为在某种程度上,这涉及到复制数据。 It's easy to get two filehandles to write to the same place, use dup() or the like, but the opposite is more tricky. 使两个文件句柄写入相同的位置,使用dup()或类似方法很容易,但是相反的过程则比较棘手。 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. 它可能涉及将模块推入(通常的示例是“ connld”到流上),尽管老实说我从未见过使用过它,所以我很想亲自看看一个有效的代码示例。
Best reference I can give is "Advanced Programming in the UNIX Environment" by Stevens. 我能给的最好的参考是Stevens的“ UNIX环境中的高级编程”。
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. 在下面说R时,上面的解决方案是一个稍微重一点的版本,它只是fork / exec-ing并将孩子的句柄重定向到其他地方。 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. Fork()不是轻量级函数。 If the spirit of the question is to do so without fork/exec, then I'm not sure, I'd love to know, too. 如果问题的实质是在没有fork / exec的情况下这样做,那么我不确定,我也想知道。 If fork/exec is okay, then directly using it or using popen() will hack it. 如果fork / exec没问题,那么直接使用它或使用popen()都会对其进行破解。
freopen
is not a good idea for redirecting stdout. 对于重定向标准输出, freopen
不是一个好主意。 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). 它不一定会重用相同的文件描述符号,因此子进程可能不会继承新的stdout(或者最终可能根本没有stdout)。 It's better to use open
and then dup2
or close(0)
then open
to create a new target for stdout. 最好先使用open
然后使用dup2
或close(0)
然后使用open
创建一个新的stdout目标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.