繁体   English   中英

模棱两可的 fread()/fwrite() 文档

[英]Ambiguous fread()/fwrite() documentation

在 RTFM 之后,我现在有点不清楚如果返回值小于请求元素的数量,我可以从 fread()/fwrite() 的返回值中真正推断出什么。

首先考虑

nhave = fread(dst, 1, nwant, fp);

从 C17 标准( 7.21.8.1/3 ):

fread function 返回成功读取的元素数,如果遇到读取错误或文件结尾,可能小于nwant

因此,如果返回时 nhave < nwant,则可能存在读取错误或 eof(但也可能有其他原因)。 因为它是if而不是only if ,所以在这种情况下不能得出feof(fp) if !ferror(fp)的结论。 如果!ferror(fp) ,根据标准,它仍然可以成功读取(nhave 字节)。

MSDNcppreference.com的写法相同。

但随后POSIX.1-2017

成功完成后, fread() 将返回成功读取的元素数,仅当遇到读取错误或文件结尾时才小于nwant

因此,如果返回时 nhave < nwant,则一定存在读取错误或 eof(不可能有其他原因)。 因此,在这种情况下,如果!ferror(fp)可以得出feof(fp)的结论。 虽然与 C 标准中的规范不同,但此行为并未标记为 POSIX 中 C 标准的扩展。

并从 Linux(符合 POSIX 的平台)上的 fread(3) 手册页:

如果发生错误或到达文件末尾,则返回值是一个短项目计数(或零)。

形式上,这是与 POSIX 相反的 (.) 语句。

现在考虑 fwrite(),

nhave = fwrite(src, 1, nwant, fp);

让我们从POSIX.1-2017开始:

fwrite() function 应返回成功写入的元素数,如果遇到写入错误,可能会小于nwant

因此,如果 nhave < nwant,则可能(但不必)出现写入错误。 在这种情况下不能得出ferror(fp)但需要检查。

MSDNcppreference.com的写法相同。

但是,根据 C17 标准( 7.21.8.2/3 ),可以得出更多结论:

fwrite function 返回成功写入的元素个数,只有遇到写入错误才会小于nwant

因此,在这种情况下, nhave < nwant 确实意味着写入错误,因此意味着ferror(fp)

这比上面 fread() 的情况更奇怪,因为 POSIX、Windows 和 C++ 都应该遵循 C 标准。

那么,这里发生了什么? 只是草率的措辞? 特别是从程序员的角度来看:

我是否可以假设 fread() 的返回值的 POSIX 措辞(如上所示)也适用于 C/C++/Windows/...,即 nhave < nwant 是否暗示读取错误(因此,ferror(fp))还是 eof(因此,feof(fp))?

我是否可以假设 fwrite() 的返回值的 C 措辞也适用于 C++/Windows/POSIX/...,即 nhave < nwant 是否暗示写入错误(因此,ferror(fp)) ?

那么,这里发生了什么? 只是草率的措辞?

我认为您对单词的解析过于精细,如果您愿意,可以将其描述为规范的草率措辞。

首先考虑fread() C17 说,

fread function 返回成功读取的元素个数,如果遇到读取错误或文件结尾,可能小于nmemb

我承认该措辞没有明确 state 错误或文件结尾是要读取的项目少于请求的唯一原因,但如果这不是意图,那么为什么会出现错误和文件结尾条件有没有提到?

fwrite的 C17 措辞是明确的:

fwrite function 返回成功写入的元素个数,只有遇到写入错误才会小于 nmemb。

比较两者,可以遵循两种不同的推理方式:

  1. 这两个函数是相似的,因此fread的模棱两可的措辞应以与fwrite明确指定的相同的“仅当”意义解释,或者

  2. 如果打算进行相同的解释,则会对两者使用相同的措辞。

我发现第一个更有说服力,特别是考虑到它还解释了为什么fread文档甚至提到错误和文件结束条件。 我完全准备好接受,尽管委员会有最好的意图,但规范的语言并不完美。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM