在RTFM之后,如果返回值小于请求元素的数量,我现在有点不清楚我可以从fread()/fwrite()的返回值中真正推断出什么。
首先考虑
nhave = fread(dst, 1, nwant, fp);
出自C17标准(7.21.8.1/3):
从文件中读函数返回成功读取的元素数目,如果遇到读取错误或文件结束符,该数目可能小于nwant。
因此,if nhave <在返回时,>可能是读取错误或错误(但也可能有其他原因)。由于是,而非仅当,因此在这种情况下,如果!ferror(fp)
,则不能得出feof(fp)
。如果是!ferror(fp)
,根据标准,它仍然可以成功读取(nhave字节)。
MSDN和cppreference.com的措辞相同。
但是POSIX.1-2017:
在成功完成后,只有在遇到读错误或文件结束时,fread()才会返回成功读取的元素数小于nwant的元素数。
因此,if nhave<在返回>时,必须有读取错误或错误(不可能有其他原因)。因此,在这种情况下,如果!ferror(fp)
,则可以得出feof(fp)
。虽然与C标准中的规范不同,但此行为并未标记为POSIX中C标准的扩展。在返回>
从Linux(一个posix兼容平台)的readad(3)手册页:
如果发生错误,或者到达文件末尾,返回值是短项计数(或零)。
正式地说,这是POSIX的反向(!)语句。
现在考虑fwrite(),nhave = fwrite(src, 1, nwant, fp);
让我们从POSIX.1-2017开始:
fwrite()函数应返回成功写入的元素数,如果遇到写入错误,该数可能小于nwant。
因此,if nhave<如果>可能(但不一定)是写错误。在这种情况下,我们不能得出ferror(fp)
的结论,但需要检查。如果>
MSDN和cppreference.com的措辞相同。
然而,根据C17标准(7.21.8.2/3),我们可以得出更多的结论:
写入文件函数返回成功写入的元素数,只有在遇到写入错误时才小于nwant。
因此在这种情况下,nhave <nwant意味着写错误,因此ferror(fp)
。>
这比上面的fread()更奇怪,因为POSIX、Windows和c++都应该遵循C标准。
这是怎么回事?只是措辞草率?特别是从程序员的角度来看:
我可以假设fread()返回值的POSIX措辞(如上所述)也适用于C/c++/Windows/…,即没有<我想暗示一个读错误(因此,error(fp))或eof(因此,feof(fp))?>
我可以假设fwrite()的返回值的C措辞(如上所述)也适用于c++/Windows/POSIX/…,即没有<我想暗示一个写错误(因此,error(fp))?>
那么,这里发生了什么?只是措辞草率?
我认为你把词语分析得太细致了,如果你愿意的话,你可以把它描述为说明书的草率措词。
首先考虑fread()
。C17说,
fread
函数返回成功读取的元素个数,如果读取错误或文件结束,可能小于nmemb
遇到。
我承认,这种措辞并没有明确指出error或end- file是读取项少于请求项的唯一原因,但如果这不是意图,那么为什么要提到error和end- file条件呢?
fwrite
的C17措辞是明确的:
fwrite
函数返回成功写入的元素数,只有在遇到写入错误时才会小于nmemb。
比较两者,人们可以遵循两种不同的推理路线:
-
这两个函数应该是类似的,所以对于
的显式指定进行感知fread
的模棱两可的措辞应该用相同的"only if"来解释。按照fwrite
, OR -
如果有相同的解释,这两者应该使用相同的措辞。
我发现第一个更有说服力,特别是考虑到它还解释了为什么fread
文档甚至提到错误和文件结束条件。我完全准备接受这个事实,尽管委员会的意图是好的,但规范的语言并不完美。