从C重新路由stdin和stdout

问题描述 投票:65回答:8

我想重新打开stdinstdout(也许在我正在的时候打开stderr)文件句柄,以便将来对printf()putchar()puts()的调用将转到该文件,以后对getc()等的调用将来自文件。

1)我不想永久失去标准的输入/输出/错误。我可能想稍后在程序中重用它们。

2)我不想打开新的文件句柄,因为这些文件句柄将必须大量传递或全局传递(颤抖)。

3)如果无法帮助,我不想使用任何open()fork()或其他与系统有关的功能。

因此,基本上可以做到这一点:

stdin = fopen("newin", "r");

并且,如果有,如何获得stdin的原始值?我是否必须将其存储在FILE *中并稍后再取回?

c redirect stdio
8个回答
82
投票

为什么使用freopen()? C89规范的尾注之一是freopen()的相应部分的答案:

116。 <stdio.h>函数的主要用途是更改与标准关联的文件文本流(freopenstderrstdin),因为这些标识符不必是值可修改的左值由stdout函数返回可能被分配。

fopen通常被滥用,例如freopen。这比stdin = freopen("newin", "r", stdin);更可移植。这两个表达式都试图分配给fclose(stdin); stdin = fopen("newin", "r");,但不能保证可分配。

使用stdin的正确方法是忽略分配:freopen


16
投票

我认为您正在寻找类似freopen("newin", "r", stdin);的东西>


10
投票

这是Tim Post方法的修改版本;我使用/ dev / tty而不是/ dev / stdout。我不知道为什么它不适用于stdout(这是/ proc / self / fd / 1的链接):


9
投票

os函数freopen()应该提供您所需要的内容


9
投票
freopen("log.txt","w",stdout);
...
...
freopen("/dev/tty","w",stdout);

3
投票

freopen("/my/newstdin", "r", stdin); freopen("/my/newstdout", "w", stdout); freopen("/my/newstderr", "w", stderr); ... do your stuff freopen("/dev/stdin", "r", stdin); ... ... 解决了简单的部分。如果您什么都没读并且愿意使用POSIX系统调用(例如printf("Stdout is descriptor %d\n", fileno(stdout)); freopen("/tmp/newstdout", "w", stdout); printf("Stdout is now /tmp/newstdout and hopefully still fd %d\n", fileno(stdout)); freopen("/dev/stdout", "w", stdout); printf("Now we put it back, hopefully its still fd %d\n", fileno(stdout)); freopen),那么保持旧的stdin并不难。如果您开始阅读它,那么所有的赌注都将关闭。


3
投票

同时,有一个C源代码库将为您完成所有这些操作,从而重定向stdout或stderr。但是很酷的部分是,它可以让您为拦截的流分配任意数量的回调函数,从而可以轻松地将一条消息发送到多个目标,数据库,文本文件等。


0
投票

这是最容易获得,方便且有用的方法

© www.soinside.com 2019 - 2024. All rights reserved.