fgetc():只检查EOF就足够了吗?

fgetc():只检查EOF就足够了吗?,c,file-io,C,File Io,在web上的各种示例中,fgetc()是这样使用的: FILE *fp = fopen(PATH, "r"); if (fp == NULL) { perror("main"); exit(EXIT_FAILURE); } int ch; while (ch = fgetc(fp) != EOF) { // do something } 但根据fgetc()的手册页 如果发生读取错误,则会显示错误 应设置水流指示器, fgetc()应返回EOF、[CX]和 应设置

在web上的各种示例中,
fgetc()
是这样使用的:

FILE *fp = fopen(PATH, "r");

if (fp == NULL) {
    perror("main");
    exit(EXIT_FAILURE);
}

int ch;

while (ch = fgetc(fp) != EOF) {
    // do something
}
但根据fgetc()的手册页

如果发生读取错误,则会显示错误 应设置水流指示器, fgetc()应返回EOF、[CX]和 应设置errno以指示错误


我也需要检查一下吗?怎样做呢?

你可以马上与ferror(3)核对一下:

while (EOF != (ch = fgetc(fp)))
   // do something

if (ferror(fp) != 0)
   // error handling
如果发生错误,ferror将返回非零

如果要在发生错误后使用fp,则需要使用clearerr清除错误标志:

clearerr(fp);

循环直到
fgetc
返回
EOF
完全可以。之后,如果您想知道循环是由于到达文件末尾还是由于错误而结束,则应调用
ferror
feof
。如果你不在乎,你可以跳过电话


请注意,无论您是检查feof还是FEROR,这都很重要,因为流的错误指示器是粘性的,即使当达到eof是导致fgetc失败的原因时,也可以计算为真。通常,您应该使用feof进行检查,如果返回false,则认为循环由于新错误而停止。

这是规范所说的:

函数的作用是:将下一个字节作为转换为整数的无符号字符

以下宏名称应定义为负整数常量表达式:EOF

只要将返回值存储在
int
而不是
char
中,检查
EOF
就足够了,因为它保证不表示有效的字符值


此外,在您的代码中:

while (ch = fgetc(fp) != EOF)
应该是:

while ((ch = fgetc(fp)) != EOF)

由于
,因此需要附加括号=
的优先级高于
=

@Helper方法:您刚刚在手册摘录中引用了这条语句。您需要在赋值周围加括号:
while((ch=fgetc(fp))!=EOF)
,但有了该修复,只检查EOF就足够了。您将获得错误的EOF或实际EOF;如果愿意,可以在循环之后消除这两种情况的歧义。