【问题标题】:switch between writing to file and stdout在写入文件和标准输出之间切换
【发布时间】:2011-11-05 21:17:56
【问题描述】:

我想在写入文件和写入stdout 之间切换 我不能使用fprintf,只能使用printffreopen 像这样:

for(size_t i;i<100;++i)
{
     if(i%2)
     {
        freopen("tmp","w",stdout);
        printf("%d\n",i);
     }
     else
     {
        //return to write to stdout?
        printf("%d\n",i);
     }
}

我怎样才能重新写信给stdout

更新

我写的是跨平台应用,dup不能用。

【问题讨论】:

  • @Yakov,那么回答第一个问题。
  • @unkulunkulu 为什么它真的很重要这个约束无法解决,因为它是我系统的组成部分,我只能说。
  • @Yakov,因为它很奇怪,我们想知道为什么要变得更好。

标签: c cross-platform printf stdout iostream


【解决方案1】:

永远不要使用freopen。它不能达到你想要的效果,而且是一个非常危险的功能。如果失败,唯一安全的做法是立即终止程序或确保不再访问stdout

有一种方法可以使用dupdup2 在 POSIX 系统上执行您想要的操作。它看起来像这样:

fflush(stdout);
int old_stdout = dup(1);
int new_stdout = open("whatever", O_WRDONLY|O_CREAT, 0666);
dup2(new_stdout, 1);
close(new_stdout);
/* use new stdout here */
fflush(stdout);
dup2(old_stdout, 1);
close(old_stdout);

【讨论】:

  • 我真的不确定你对freopen 的可怕警告是基于什么。有参考吗?另外,pubs.opengroup.org/onlinepubs/009695399/functions/freopen.html 表示freopen 通常用于将stdinstdoutstderr 重新附加到其他文件。
  • 在您提供的链接中查看此文本:“无论后续打开是否成功,都应关闭原始流。”因此,如果打开新文件失败,stdout 将被关闭,并且由于它已被关闭,任何使用 stdout 的函数(例如 printf)现在都使用无效的 FILE * 并因此调用未定义的行为。
  • 我认为没有什么能阻止你重新分配这些,所以你仍然可以优雅地处理这个。
  • 不允许分配给stdout。事实上,glibc 只是唯一允许它的系统,虽然他们在文档中明确允许它,但分配给stdout 实际上并没有被所有内部函数尊重(其中一些没有看到它是由于符号可见性或复制重定位相关的错误...)。根据标准,stdinstdoutstderr 是扩展为 FILE * 类型表达式的宏。没有理由期望它们甚至应该是左值,更不用说可修改了。
  • 对。不过,我会稍微缓和一下警告,因为在程序初始化时使用 freopen 应该是安全的,此时可以处理关闭标准句柄之一。
【解决方案2】:

您需要dup 文件描述符,然后重新打开到打开的描述符。为什么不能使用fprintf? (这是作业吗?)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 2014-12-28
    • 2018-12-07
    相关资源
    最近更新 更多