prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 12.34

Q一旦我使用了freopen,我该如何找回原来的stdout(或stdin)?


A没有好的方法。如果你需要切换回来,最好的解决方案是最初就不要使用freopen。尝试使用你自己的显式输出(或输入)流变量,你可以随意重新分配它,同时保持原始的stdout(或stdin) 不受影响。例如,声明一个全局的

	FILE *ofp;
,并将所有对printf(... )的调用替换为fprintf(ofp,... )。 (显然,你还需要检查对putcharputs的调用。)然后你可以将ofpstdout设置为任何值。

你可能想知道是否可以完全跳过freopen,并做类似

	FILE *savestdout = stdout;
	stdout = fopen(file, "w");	/* WRONG */
的操作,以便稍后通过执行stdout来恢复
	stdout = savestdout;		/* WRONG */
,但像这样的代码不太可能奏效,因为stdout(和stdinstderr)通常是不能重新赋值的常量(这就是为什么freopen存在的原因)。

在调用freopen来打开一个文件替换它之前,可能有可能以一种不可移植的方式保存流的信息,以便以后可以恢复原始流。最直接可靠的方法是使用系统特定的调用(如dupdup2)来操作底层的}`;`文件描述符,如果可用的话(示例)。另一种方法是复制或检查`;`结构的内容,但这极其不可移植且不可靠。`FILE结构的内容,但这极其不可移植且不可靠。

在某些系统上,你可能能够重新打开一个特殊的设备文件(例如,现代 Unix 版本下的/dev/fd/1),它仍然连接到(例如)原始的标准输出。在某些系统上,你可以显式地重新打开控制终端(请参阅问题 12.36),但这不一定是你想要的,因为原始的输入或输出(即调用stdinstdout之前freopen的内容)可能已经从命令行重定向了。

所有这些都与最初由freopen执行的标准 I/O 重定向有关,影响了调用freopen的同一个程序中的 I/O 调用。如果你想捕获子程序执行的结果,freopen可能也无法正常工作;请参阅问题 19.30

其他链接:示例


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管