【问题标题】:Can input/output via respective standard I/O streams fail?通过各自的标准 I/O 流输入/输出会失败吗?
【发布时间】:2014-11-17 13:55:06
【问题描述】:

fgetsfputs 等标准输入/输出函数可能会因各自的读取或写入错误而失败。这是有道理的,因为文件系统权限和空间限制可能会阻止程序读取或写入文件。

但是,我很难想象在相应标准 I/O 流(stdinstdoutstderr)上的输入/输出操作会失败的情况,因为它们似乎是在概念上比文件系统中的典型文件更抽象。

例如,以下fputs 调用是否有可能返回表示写入错误的EOF

fputs("Hello world!\n", stdout)

C99 标准是否明确或隐含地保证在各自的标准 I/O 流上成功的输入/输出操作?还是在合规的理论实现上可能会失败?

我怀疑标准 I/O 流上可能会出错,因为 puts 函数和 gets 函数 Returns 部分都提到了失败返回值的可能性; putsgets 分别显式写入/读取 stdout/stdin 流,标准 I/O 流上的错误似乎是隐含的。

但是,这同样适用于stderr 流吗?可能不是,因为perror 函数没有提及错误条件,也没有返回表示失败的值(perror 有一个void 返回类型)。

【问题讨论】:

  • 输入函数,根据他们的定义,不能得到 output 操作的错误。此外,您的示例存在缺陷,因为 fgets 永远不会返回 EOF
  • 失败总是可能的。想象一下,您的进程位于管道中间,而其左侧或右侧的进程被终止。
  • 标准 I/O 流可以重定向到文件/从文件重定向。因此,可以应用相同的限制
  • @VilhelmGray:写入读取器已被杀死的管道(假设已处理 SIGPIPE)将​​与 EPIPE 出错,它不会永远阻塞等待不可能回来的读取器。虽然我不认为 C 涉及到这种详细程度,但肯定不能保证读取或写入不会失败。
  • 由于其内在性质,无法预先保证输入/输出操作:它们与外部世界一起操作,程序无法控制其外部;所以它们总是在输入/输出过程中可能发生的潜在问题(磁盘已满、终端关闭、网络关闭等)。

标签: c file-io c99


【解决方案1】:

标准 IO 流保证存在。它们不能保证在 IO 操作时打开。作为一个进程通常从其父进程(无论是外壳还是其他任何东西)继承其 IO 流,它们可以处于绝对任何状态:直接到控制台/键盘,重定向到/来自文件或管道或套接字,或者...关闭.

所以,是的,即使在标准流上,以及输入(关闭)或输出(设备上没有更多空间,...)上,任何 IO 操作都可能出现错误。

编辑:

您提到了 perror 的一个特殊情况,它具有 void 返回类型。这并不意味着 perror 不会失败:如果它被重定向它就可以。但问题更多的是我在哪里可以写我不能写错误条件?!由于它已经在错误处理程序中,如果它无法写入 perror 的结果,通常程序不能做得更好:-(

【讨论】:

  • 我认为第 7.19.3 节第 7 节保证所有三个标准 I/O 流最初都是打开的。这是否意味着在 main 函数开始一段时间后,这些流可能会关闭?
  • 似乎将标准流传递给fclose 是合法的:How to close stdout and stderr in c
  • perror 的情况值得关注,因为它无法验证是否发生错误——如果在 @ 上调用 freopen,则在空间不足的情况下可能会出错例如,987654326@ 将其输出重定向到文件。但是,最好在单独的专用 StackOverflow 问题中回答;我相信标准中有足够的隐含内容可以证明标准流可能存在读/写错误。
猜你喜欢
  • 2017-09-20
  • 1970-01-01
  • 2019-10-03
  • 1970-01-01
  • 2021-02-28
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多