【发布时间】:2013-05-12 13:22:04
【问题描述】:
什么样的库函数面临什么样的错误会影响errno并将其设置为非零值?在下面的程序中,我打算使用if(errno!=0) 作为条件来检查我使用的库函数是否正常运行,这就是我发现的(见下面的代码):
首先我用if(errno!=0) 来测试一个文件是否已经用fopen() 成功打开。如果我尝试打开一个不存在的文件,则 errno 设置为非零(在我的情况下为 2),并通过在每个阶段打印出 errno 的值来验证。但是,如果我打开一个现有文件,则 errno 的值将保持为零,因为 fopen() 会正确打开该文件。在这件事上,if(errno!=0) 是我已注释掉的if(pFile==NULL) 的完美替代品。
如果文件成功打开,errno 仍然是0,则控制移动到第一个else 块。这就是我对errno 的行为感到困惑的地方。在这里,由于我已在 r(read) 模式下打开文件并尝试使用fputc() 对其进行写入,因此我希望生成的写入错误将errno 设置为非零,就像无法成功打开文件时由fopen()设置。但即使在使用fputc() 写入失败后,errno 的值仍然为零。 (这可以通过在错误写入后打印errno 的值来验证)。
为什么会这样?为什么设置errno 的一个函数fopen() 面临I/O 错误,而其他函数fputc() 面临的写入错误不影响errno?如果是这样,我们如何可靠地使用errno 作为错误指示器? 我是否使用 errno 来测试 fopen() 是否成功运行,而不是不明智地使用“if(pFile==NULL)”?我将感谢您对此的分析回答。
#include <stdio.h>
#include <errno.h>
int main ()
{
FILE * pFile;
printf("%d\n",errno);
pFile = fopen("D:\\decrypt.txt","r");
printf("%d\n",errno); // Prints 0 if fopen() successful,else 2
//if(pFile==NULL) perror("Error opening file");
if (errno!=0) perror ("Error opening file");
else
{
fputc ('x',pFile);
printf("%d\n",errno); //errno shows 0 even after write error
//if (ferror (pFile))
if (errno!=0) //Condition evaluates false even if faulty write
{
printf ("Error Writing to decrypt.txt\n");
}
fclose (pFile);
}
return 0;
}
【问题讨论】:
-
POSIX says: "只有当函数的返回值表明 errno 的值有效时,才应该检查它。"
-
@Mat C 标准是怎么说的?
..when it is indicated to be valid by a function's return value.是什么意思?你能把它放在一个更详细的答案中吗? -
@Rüppell'sVulture 查看链接以获得更多答案。并非每个库函数都设置 errno。 C标准没有说明哪些函数设置了errno,甚至设置errno也不一定是实际错误。
-
@Rüppell'sVulture:hmjd 已经引用了 C 标准。