【问题标题】:Changing the value of stdout in a C++ program在 C++ 程序中更改标准输出的值
【发布时间】:2008-12-17 21:45:35
【问题描述】:

我有一个 Windows C++ 程序正在执行以下操作:

文件* pf = ...; *标准输出= *pf; // stdout 在 stdio.h 中定义

我正在寻找有关更改标准输出文件句柄的值时会发生什么的解释。这只是重定向标准输出的一种方式吗?

-cr

【问题讨论】:

  • 我过去曾考虑过这样做,但从未想过,因为我也没有找到好的答案

标签: c++ c stdout filehandle


【解决方案1】:

是的,当您更改标准输出时,您实际上是在将其重定向到其他地方。但是,您应该像那样直接分配给 stdout。如果你想重定向标准输出,你应该改用freopen()

您永远不应该直接操作 FILE 对象 - 您应该将它们视为不透明类型,并且只能通过 <stdio> 库中的函数与它们交互。 Jonathan 列出了一些很好的理由。

来自 C99 标准,第 7.19.3 节,第 6 段:

用于控制流的 FILE 对象的地址可能很重要;一份 FILE 对象不需要代替原始对象。

【讨论】:

  • 这段代码不是我写的。它位于工具包供应商的一些示例代码中。
【解决方案2】:

如果你通过赋值而不是使用指定的工具来更改stdout(在 C 中,freopen() 正如 Adam Rosenfield 所说 - 并且通过扩展,在 C++ 中),那么你会让自己承担各种责任。

  • 尚不清楚cout 是否也会被重定向。
  • 您可能会泄漏文件描述符(这可能无关紧要)。
  • 您可能无法正确刷新原始标准输出 - 丢失信息。
  • 您可能会泄漏与原始文件指针相关的内存(这同样可能无关紧要)。
  • 如果有任何东西关闭 pf,那么您需要为双重释放错误(崩溃)负责。

干净利落地完成工作要好得多。

(演示代码不一定是由供应商编码团队中最有经验的人编写或审查的。如果它看起来很可疑,那可能是因为它很可疑。)

【讨论】:

  • 最重要的是,您调用了未定义的行为。 C 标准非常清楚使用 FILE 的副本代替原始调用 UB 这一事实,我相信 C++ 标准会同意 C 的这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-24
  • 1970-01-01
  • 2012-02-12
  • 2013-02-02
  • 2017-02-03
  • 2021-08-13
相关资源
最近更新 更多