C EOF是否设置了errno?
我总是为系统调用的返回值而挣扎——它们太不一致了! 通常我检查它们是否为NULL或-1,然后调用C EOF是否设置了errno?,c,unix,system-calls,C,Unix,System Calls,我总是为系统调用的返回值而挣扎——它们太不一致了! 通常我检查它们是否为NULL或-1,然后调用perror。但是,对于fgets,手册页显示: gets()和fgets()在成功时返回s,在错误时或在未读取字符时出现文件结尾时返回NULL 这意味着返回值NULL不一定是错误-也可能是EOF。到达文件末尾时是否设置了errno?在这种情况下,我还能打电话给Peror吗 如果不是,那么,与EOF相比,判断调用是否返回错误的常用方法是什么。我想使用perror和空字符串表示错误,使用自定义字符串表示
perror
。但是,对于fgets
,手册页显示:
gets()
和fgets()
在成功时返回s,在错误时或在未读取字符时出现文件结尾时返回NULL
这意味着返回值NULL
不一定是错误-也可能是EOF。到达文件末尾时是否设置了errno?在这种情况下,我还能打电话给Peror吗
如果不是,那么,与EOF相比,判断调用是否返回错误的常用方法是什么。我想使用
perror
和空字符串表示错误,使用自定义字符串表示EOF。使用ferror
和feof
区分错误和EOF。如果有错误的话,没有通用的方法来准确地找出错误是什么,但是你可以知道有错误
标准C(f)get
(和(f)getc
)不需要设置errno
,尽管一致性库实现可以随意将errno
设置为非零值
Posix确实要求
(f)获取{c,s}
设置errno
读取错误,但这仅在确定存在读取错误后(通过调用ferror
)才有帮助。同样重要的是要记住,库函数从不将errno
设置为0,但即使没有错误发生,也可能将errno
设置为非零值。因此,您不能测试errno
来代替检查任何库函数的错误返回,包括fgets
。由于文件结尾不是错误,errno
可能不会在EOF上修改,所以在这种情况下它的值是没有意义的。根据fputs自己的文档,是的,EOF设置了errno。手册页间接地推断了这一点,而不是直截了当地说出来,希望能加以修改。函数fputs返回一个整数,成功时为正,失败时为EOF。因此,错误处理FPUT的关键是设置一个代码块,在调用FPUT时检查其返回值。下面是我如何被教导处理fputs错误的一个片段
if (fputs(buffer, stdout) == EOF)
{
fprintf(stderr, "fputs returned EOF: %s\n", strerror(errno));
// .. and now do whatever cleanup you need to do.
// or be lazy and exit(-1)
}
在这里,我将缓冲区的内容写入标准输出,并检查fputs是否返回EOF。EOF表示设置了错误代码,因此只要遵循FPUT手册页上的文档,就应该能够创建一组if语句来检查errno可以设置为的各种错误代码
(1) 什么是缓冲区?我在别处声明的一些字符数组
(2) fprintf做什么?它将输出打印到传入的文件描述符,这在本例中是标准错误(stderr…它像stdout一样打印到控制台,但对于错误)
(3) 什么是strerror?它是一个在string.h头中定义的函数,用于为传入的错误代码打印错误信息。它包含errno可以设置为的每个错误代码的信息。头文件string.h不应与strings.h混淆,后者是不包含strerror(3)的BSD linux头文件
编辑:好吧,我搞砸了。你在寻找关于FGET而不是FPUT的答案
要检查FGET上的错误,请执行以下操作
if (fgets(buffer, BUF_SIZE, myFile) == NULL)
{
// print out error as a string to stderr
fprintf(stderr, "fgets error occurred: %s\n", strerror(errno));
// do cleanup
}
// special: you also need to check errno AFTER the if statement...
问题是,如果流变得不可读(这可能是由于权限或试图读取处于写入模式的内容),那么您在这方面得到错误的唯一方法就是。在网络的情况下,有可能在阅读过程中有什么东西切断你的连接,在这种情况下,你还需要检查FFIF if语句之后的错误代码。但如果出现问题,它将设置错误代码
至少如果手册页是正确的话。有关更多详细信息,请参阅linux手册页。唯一可以设置的错误代码是“我看不见这个东西”代码,它是errno==EBADF@Xufeng:不,它直接从
文件
对象获取信息,以某种特定于实现的方式。@Xufeng:不太可能,因为errno
尚未设置(至少不是由ferror
或(f)get
),因此,perror
的结果充其量只是误导。你所能做的就是打印一些本地化版本的I/O error
,但是perror
也不会做得更好,即使设置了errno
。哦,既然你说fgets没有设置errno,所以我做了一些研究,发现fgets一开始就不是一个系统调用@徐峰:是的,这是这里要记住的重要事情。系统调用在使用errno
时是一致的。但本手册第2节中的功能仅为系统调用gets
和fgets
是标准C库函数,标准C库是可移植的,对unix特定接口的存在一无所知,如errno
@JanHudec:standard C包含头文件
的定义,其中包括errno
的定义:"... 它扩展为具有int类型和thread local storage duration的可修改左值,其值由多个库函数设置为正错误数。“其中一个函数是strtod
,它也不是系统调用。注意:1)OP的帖子位于fgets()
而不是fputs()
.2)根据C11标准,fputs()
对errno
不起作用。可能它在*nix内起作用。@chux:C标准没有说fputs()
对errno
不起作用。它没有说它是否起作用。7.5p3:无论是否存在错误,errno
的值可通过库函数调用设置为非零,前提是errno
的使用未在本Interna中的函数描述中记录