fgetc,检查EOF

fgetc,检查EOF,c,eof,fgetc,C,Eof,Fgetc,在《Linux系统编程》一书中,我读过如下内容: fgetc将读取为无符号字符的字符转换为int或 EOF在文件末尾或出现错误时。使用fgetc的常见错误是: char c; if ((c = fgetc()) != EOF) {...} 此代码的正确版本为: int c; if ((c = fgetc()) != EOF) { printf("%c", (char)c); ... } 那么,为什么我不能在与EOF进行比较之前将返回值强制转换为char?为什么我必须将EOF与int进行精确比

在《Linux系统编程》一书中,我读过如下内容:

fgetc
将读取为
无符号字符的字符
转换为
int
EOF
在文件末尾或出现错误时。使用
fgetc
的常见错误是:

char c;
if ((c = fgetc()) != EOF) {...}
此代码的正确版本为:

int c;
if ((c = fgetc()) != EOF) { printf("%c", (char)c); ... }

那么,为什么我不能在与
EOF
进行比较之前将返回值强制转换为
char
?为什么我必须将
EOF
int
进行精确比较?由于
EOF
定义为
-1
,它通常不是强制转换为
char

是否存在不正确的平台/编译器?

您不能将返回值强制转换为char,因为返回值可能是
EOF
,并且
EOF
值取决于系统,并且不等于任何有效的字符代码

通常它是
-1
,但您不应该假设它是

请从以下列表中查看这一伟大的答案:

如上面的片段所示,如果getchar 返回值被分配给一个字符

  • 如果类型char是有符号的,并且如果EOF(通常)定义为-1,则 将删除十进制值为255的字符(C中的“\377”或“\xff”) 符号扩展,将与EOF比较,提前终止 输入。(假设为8位字符)

  • 如果类型char是无符号的,则实际的EOF值将被截断(通过 丢弃其高阶位,可能导致255或 0xff),将不会被识别为EOF,从而导致 无限的投入

  • 希望有帮助

    编辑:(在这个答案上添加了@FatalError注释,这在c-faq网站上有解释,但我觉得这更清楚)


    “如果将其强制转换为char,则EOF将采用与某个有效字符相同的值,因此无法与该字符区分。仅此一点就足以证明结果不是char”@FatalError comment。

    在与EOF进行比较之前,将值指定给
    char
    时有两种可能性:

    • char
      是一个有符号的值。在这种情况下,有一个合法字符(通常是ÿ,带分音符的拉丁文小写字母Y,U+00FF)会被误解为EOF
    • char
      是一个无符号值。在这种情况下,EOF将被转换为0xFF,然后作为正值提升为
      int
      ,这将永远不会与作为负值的EOF进行比较
    不管是哪种方式,该程序都会在某些时候行为不端


    存在(或者更准确地说,过去是)编译器错误的可能性,例如赋值正确,但赋值未用于比较。这将导致代码看起来工作正常,即使它不是。幸运的是,这不太可能是现代编译器中发现的问题。

    那又怎样?我不明白。施放字符后,字符将等于'-1',不是吗?@p相反,标准实际上并不要求仅
    char
    是有符号的还是无符号的。如果你想要一个有保证的签名字符,你必须使用
    signed char
    @Corbin-Hm,我想,这个字符总是有签名的。谢谢,我来看看standatd@cacho我怀疑它,但我没有找到任何关于它的信息。感谢如果您将其强制转换为
    char
    ,则
    EOF
    将采用与某个有效字符相同的值,因此与该字符无法区分。仅此一点就足以证明不会将结果变成
    char
    。可能重复@jww:这个问题没有使用
    feof()
    ,因此它不是“”的重复。