fread 和 ferror 不要设置 errno

fread and ferror don't set errno

我正在尝试检查 fread() 何时引发错误,因此我使用 ferror().

chunk = fread(buf, 1, 100, file);
if (ferror(file))
  {
    return errno;
  }

但是,ferror() 手册页(man 3 ferror,或者 man ferror)说:

ERRORS
These functions should not fail and do not set the external variable errno.

那么,虽然 fread()ferror() 没有设置 errno,但我怎么知道读取文件时发生的错误类型?

这些函数不使用 errno,因此您也不应该使用。

值得注意的是,您可以从fread()的return值判断是否一切顺利。如果 fread() 的 return 值与传递的 nmemb 参数不同(在您的情况下为 100),那么您要么到达文件末尾,要么在读取文件时发生错误(source).所以只在那种情况下测试:

完全放弃使用 errno:

chunk = fread(buf, 1, 100, file);
if (chunk != 100) { // If fread() returns a number different to the nmemb parameter, either error or EOF occured
    if (ferror(file))
      {
        printf("Error occured while reading file.");
        return -1; // Or what ever return value you use to indicate an error
      }
}

你不能从这里到达那里。

fread 不会设置 errno(正如您所发现的),因此您无法真正确定 特定的 错误状态;只有 一个。错误的确切性质通常取决于实现。没有基于 C 标准库的可移植方式来收集它。

对于特定的系统级错误,您可以将其转化为系统调用,可能会遇到 poor/nonexistent IO 缓冲等陷阱。 POSIX 可以为您提供一些帮助。像 readdo 这样的调用设置了 errno 并且有一组相当详细的可能结果。如果您正在使用的平台是 POSIX 兼容的,并且代码真的非常重要,需要了解,这可能是您的一个选择。

但是从 C 标准库中,除了被告知发生了错误之外,您不会找到太多信息。一般来说,你会发现你不需要更多。