【问题标题】:Does stdio always set errno?stdio 是否总是设置 errno?
【发布时间】:2012-05-27 04:14:52
【问题描述】:

stdio 流遇到错误(但不是EOF)时,将设置流的错误指示符,以便ferror() 返回非零值。我一直认为errno 提供了更多信息。但是我怎么知道呢?

一些功能的文档[例如。 man fopen under Linux] 表示errno 也将被设置。然而man fgets 根本没有提到errno。 glibc 信息页面令人放心:

除了设置与 流,对流进行操作的函数也在 与对文件进行操作的相应低级函数的方式相同 描述符。

但我不知道这个保证有多强。是C标准要求的吗?在 Visual C/C++ 中会发生什么?

【问题讨论】:

    标签: c++ c error-handling stdio errno


    【解决方案1】:

    C 标准本身不需要太多使用 errno WRT 到 stdio 函数;它指定了ferror(),但只提到了这一点

    7.13.10.3 ferror 函数 ferror 函数测试stream 指向的流的错误指示符。当且仅当为流设置了错误指示符时,ferror 函数才返回非零值。

    来自 C99 草案:http://www.vmunix.com/~gabor/c/draft.html。在大多数情况下,使用的任何实际错误代码都是由实现定义的。

    不过,Linux 上的 GNU C 库也符合 POSIX 规范:

    http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm

    在这种情况下,它们的定义要好得多。例如,如果您查看fopen 的页面:

    http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html

    您会在错误下看到很多详细信息,包括具体的 errno 代码。

    同样,几乎所有普通 linux 系统上使用的 GNU C 库都符合 POSIX 标准,因此您可以信赖这些信息;)。那些(在线)POSIX 手册页通常也比标准的 linux 系统手册页更详细(同时阅读)。

    WRT 到其他(非 POSIX)平台上的文件操作,它们将有自己的实现。不幸的是,这样的东西在标准 C 中并不是透明可移植的。不过,C++ 流确实有更标准化的错误处理。

    【讨论】:

    • 谢谢。 POSIX 定义非常有用。例如,根据他们的说法,“fgets”确实设置了 errno。我认为针对我的特殊情况的最佳策略是只为 POSIX 编写代码,然后在出现问题时解决 Windows 问题。
    • 虽然 GNU 的 fopen() 设置了 errno,但 fread() 没有,即使 POSIX 指定了(使用 "CX"标签)。任何想法为什么?
    • POSIX man page 至少没有提到这一点。不过,我注意到 linux 手册页根本没有提到 errno。
    【解决方案2】:

    根据 C11 标准第 7.21 章(“stdio.h”),只有 fgetposfsetposftell 在发生错误时写入 errno

    【讨论】:

      猜你喜欢
      • 2014-05-01
      • 1970-01-01
      • 2021-05-18
      • 2013-08-23
      • 2011-10-24
      • 2021-01-06
      • 2011-02-07
      • 2015-10-09
      • 1970-01-01
      相关资源
      最近更新 更多