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

Ambiguous fread()/fwrite() documentation

在 RTFM 之后,我现在有点不清楚如果 returned 值小于数字,我能从 fread()/fwrite() 的 return 值真正推断出什么请求的元素。

首先考虑

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

来自 C17 标准 (7.21.8.1/3):

The fread function returns the number of elements successfully read which may be less than nwant if a read error or end-of-file is encountered.

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

MSDN and cppreference.com写法相同

然后 POSIX.1-2017:

Upon successful completion, fread() shall return the number of elements successfully read which is less than nwant only if a read error or end-of-file is encountered.

因此,如果 return 上的 nhave < nwant,则 必须 存在读取错误或 eof(不能有其他原因)。因此在这种情况下,可以得出结论 feof(fp) if !ferror(fp)。虽然与 C 标准中的规范不同,但此行为在 POSIX.

中未标记为对 C 标准的扩展

并且来自 Linux(符合 POSIX 的平台)的 fread(3) 手册页:

If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).

形式上,这是 POSIX.

的相反 (!) 语句

现在考虑 fwrite(),

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

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

The fwrite() function shall return the number of elements successfully written, which may be less than nwant if a write error is encountered.

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

MSDN and cppreference.com写法相同

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

The fwrite function returns the number of elements successfully written, which will be less than nwant only if a write error is encountered.

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

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

那么,这是怎么回事?只是草率的措辞?特别是从程序员的角度来看:

我可以假设 fread() 的 return 值的 POSIX 措辞(如上所述)也适用于 C/C++/Windows/.. .,即 nhave < nwant 是否意味着读取错误(因此是 ferror(fp))或 eof(因此是 feof(fp))?

我能否假设 fwrite() 的 return 值(如上所示)的 C 措辞也适用于 C++/Windows/POSIX/...,即 nhave < nwant 是否意味着写入错误(因此,ferror(fp))?

So, what's going on here? Just sloppy wording?

我认为您对文字的分析过于细致,如果您愿意,可以将其描述为规范的草率措辞。

首先考虑 fread()。 C17 说,

The fread function returns the number of elements successfully read, which may be less than nmemb if a read error or end-of-file is encountered.

我同意该措辞没有明确指出错误或文件结尾是读取的项目少于请求的项目的唯一原因,但如果这不是本意那么为什么会出现错误和结束-是否提及文件条件?

fwrite 的 C17 措辞是明确的:

The fwrite function returns the number of elements successfully written, which will be less than nmemb only if a write error is encountered.

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

  1. 这两个函数是类似的,因此 fread 的含糊不清的措辞应该在与 [=13= 明确指定的相同的“仅当”意义上解释], 或

  2. 如果意在进行相同的解释,那么两者将使用相同的措辞。

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