[英]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 字节)。
MSDN和cppreference.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)
但需要检查。
MSDN和cppreference.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。
比较两者,可以遵循两种不同的推理方式:
这两个函数是相似的,因此fread
的模棱两可的措辞应以与fwrite
明确指定的相同的“仅当”意义解释,或者
如果打算进行相同的解释,则会对两者使用相同的措辞。
我发现第一个更有说服力,特别是考虑到它还解释了为什么fread
文档甚至提到错误和文件结束条件。 我完全准备好接受,尽管委员会有最好的意图,但规范的语言并不完美。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.