fread and ferror don't set errno
我正在尝试检查fread()何时引发错误,所以我使用ferror()。
1 2 3 4 5
| chunk = fread(buf , 1, 100, file );
if (ferror(file ))
{
return errno ;
} |
但是,ferror()手册页上说:
ERRORS These functions should not fail and do not set the external variable errno.
那么,尽管fread()和ferror()没有设置errno,我怎么知道读取文件时发生的错误类型?
- 您读过fread(3)吗?它具有记录的错误行为!
-
是的,它没有提及有关设置errno的任何内容。
-
@BasileStarynkevitch我认为他的观点就是这样。当然ferror可以告诉您发生了错误,但是由于没有记录fread来设置errno,因此他怎么能知道实际错误,如果可以的话,因为errno不会反映出点亮流错误状态的特定错误条件?
-
相关:stdio总是设置errno吗?
您不能从这里到达那里。
fread不会设置errno(如您所发现的),因此,您不能真正确定某个特定错误状态的太多信息。只有那一个。错误的确切性质通常取决于实现。没有基于C标准库的可移植方式来收集它。
对于特定的系统级错误,您可以将其限制在系统调用中,可能会遇到陷阱,例如在此期间IO缓冲不佳/不存在。 POSIX可以为您提供一些帮助。像read这样的调用会设置errno并具有相当详细的可能结果集。如果您使用的平台兼容POSIX,并且代码确实非常关键以至于无法了解,那么这可能是您的选择。
但是从C标准库中,除了被告知发生了错误之外,您不会发现太多。通常,您会发现自己并不需要更多。
-
POSIX要求fread设置错误时的errno。从POSIX文档的fread开始,"否则,如果发生读取错误,则应设置流的错误指示符,并且应设置errno来指示错误。
-
@DavidHammen:该代码段被标记为POSIX扩展名[CX]。仍然,我想知道为什么GNU不遵循此扩展。用适当的值定义_XOPEN_SOURCE / _POSIX_SOURCE时不应该吗?
这些功能不使用errno,因此您也不应该使用。
值得注意的是,您可以根据fread()的返回值判断一切是否顺利。如果fread()的返回值与传递的nmemb参数(在您的情况下为100)不同,则您到达文件末尾或读取文件(源)时发生错误。因此,仅在这种情况下进行测试:
完全放弃使用errno:
1 2 3 4 5 6 7 8
| 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
}
} |
- @BasileStarynkevitch fread已记录错误或文件末尾的行为。您需要使用ferror()来检查是否是错误,或者使用feof()来结束文件。