stdio 是不是总是设置 errno?
Posted
技术标签:
【中文标题】stdio 是不是总是设置 errno?【英文标题】: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++ 中会发生什么?
【问题讨论】:
【参考方案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”),只有 fgetpos
、fsetpos
和 ftell
在发生错误时写入 errno
。
【讨论】:
以上是关于stdio 是不是总是设置 errno?的主要内容,如果未能解决你的问题,请参考以下文章