Rüp*_*ure 6 c fopen errno fputcsv
什么样的库函数会对errno产生什么样的错误并将其设置为非零值?在我的下面的程序中,我打算用if(errno!=0)一个条件来检查我使用的库函数是否正常运行,这就是我找到的(参见下面的代码):
首先我用来if(errno!=0)测试文件是否已成功打开fopen().如果我尝试打开一个不存在的文件,则errno设置为非零(在我的情况下为2),并通过打印errno每个阶段的值来验证它.但是,如果我打开现有文件,则errno的值保持为零,因为fopen()正确打开文件.在这件事上,if(errno!=0)作为if(pFile==NULL)我所评论的完美替代品.
如果文件成功打开,errno静止0,则控件移动到第一个else块.这是我发现关于行为的混淆的地方errno.在这里,由于我已经在r(读)模式下打开文件并尝试使用它来写入fputc(),我希望得到的写错误设置errno为非零,就像fopen()它无法成功打开文件时设置的那样.但errno即使在写入失败后,该值仍然为零fputc().(这可以通过errno错误写入后的打印值来验证).
为什么会这样?为什么一个函数fopen()设置了I/O错误设置errno其他函数所面临的while写错误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;
}
Run Code Online (Sandbox Code Playgroud)
文档主要告诉您哪个函数可以设置哪些值errno,但是您需要知道一些规则:
errno为零.errno在功能指示发生错误时进行测试(并记录设置的功能errno).第一点意味着如果你想知道,例如,你是否收到了错误strtol(),你必须errno在调用它之前设置为0.
第二点至关重要; 例如,在Solaris上,在通道不是终端的许多I/O操作之后,设置errno将是ENOTTY(不是终端).没有错误; 一切都没有失败; 但是errno单独执行后续操作(而不是基于I/O操作报告的状态)将导致您认为一切都失败了.
因此,在您的代码中,即使成功创建文件流,fopen()调用也可能保留errno为非零值.你必须使用:
const char filename[] = "D:\\crypt.txt";
if ((pFile = fopen(filename, "r")) == 0)
{
fprintf(stderr, "Failed to open %s for reading (%d: %s)\n",
filename, errno, strerror(errno));
...return or exit...
}
Run Code Online (Sandbox Code Playgroud)
注意:如果需要调用可以更改的函数,请errno尽早捕获该值:
int errnum = errno;
fprintf(stderr, "Failed to open %s for reading (%d: %s)\n",
filename, errnum, strerror(errnum));
Run Code Online (Sandbox Code Playgroud)
永远不要宣告errno自己; 总是习惯#include <errno.h>这样做.
我不清楚为什么你的代码没有在fputc()通话中出错.在我的Mac OS X 10.8.3系统上,等效代码失败,errno设置为9(EBADF)'错误的文件描述符'.
这记录在哪里?它符合C标准,并受到POSIX标准的强化.
<errno.h>3
errno初始线程中的值在程序启动时为零(errno其他线程的初始值为不确定值),但任何库函数都不会将其设置为零.202)如果在本国际标准中的功能描述中没有记录errno使用,errno则可以通过库函数调用将值设置为非零,无论是否存在错误.202)因此,
errno用于错误检查的程序应在库函数调用之前将其设置为零,然后在后续库函数调用之前检查它.当然,库函数可以保存输入值,errno然后将其设置为零,只要原始值恢复,如果errno在返回之前值仍然为零.
以前版本的C标准中的措辞没有提到线程,但在其他方面类似.
注意,fopen()C标准中的描述没有提到errno.因此,允许errno按C标准设置.相比之下,该mbsrtowcs()功能被记录为设置errno为EILSEQ; 它可能无法将其设置为其他值,因为C标准说它不应该(尽管没有什么可以阻止实现,如果它对某些条件有更好的错误).
POSIX页面errno说:
许多函数提供了错误号
errno,其中包含类型int并在其中定义<errno.h>.errno只有在调用明确声明要设置的函数之后,才能定义值,直到下一个函数调用更改它或者应用程序为其赋值.值errno时,则说明是由函数的返回值有效的只应进行检查.申请应errno通过列入来获得定义<errno.h>.此POSIX.1-2008卷中的任何功能都不应设置errno为0.errno成功调用函数后的设置未指定,除非该函数的描述指定errno不应修改.未指定
errno是使用外部链接声明的宏还是标识符.如果为了访问实际对象而禁止宏定义,或者程序使用名称定义标识符errno,则行为是未定义的.存储在errno中的符号值记录在所有相关页面的ERRORS部分中.
以前版本中的措辞是类似的.