fgetc,检查EOF

时间:2012-06-15 19:48:03

标签: c eof fgetc

Linux系统编程一书中,我读过这样的文章:

  

fgetc将读取的字符作为unsigned char广告投放回int或   EOF在文件或错误结束时。使用fgetc的常见错误是:

char c;
if ((c = fgetc()) != EOF) {...}
     

此代码的正确版本为:

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

那么,在与char比较之前,为什么我不能将返回值转换为EOF?为什么我必须将EOFint完全比较?由于EOF定义为-1,它通常不会投放到char吗?是否存在不适用的平台/编译器?

2 个答案:

答案 0 :(得分:10)

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

通常是-1,但你不应该认为。

c-faq-site

中查看这个好的答案
  

如果像上面的片段中那样,getchar可以使用两种失败模式   返回值分配给char。

     
      
  1. 如果char类型已签名,并且如果将EOF定义为(通常)为-1,则为   小数值为255的字符(' \ 377'或者' \ xff'在C中)将是   符号扩展并将比较等于EOF,过早终止   输入。 (假设8位字符)。

  2.   
  3. 如果type char是无符号的,则实际的EOF值将被截断(by   丢弃其高阶位,可能导致255或   0xff)并且不会被识别为EOF,从而有效地产生   无限输入。

  4.   

希望它有所帮助!

编辑:(在此答案中添加了@FatalError评论,这在c-faq网站上有解释,但这对我来说更清楚了)

"如果将其强制转换为char,则EOF与某个有效字符的值相同,因此与该字符无法区分。仅凭这一点就足以证明不能使结果成为焦点。 @FatalError评论。

答案 1 :(得分:3)

在与EOF比较之前,将值分配给char时有两种可能性:

  • char是签名值。在这种情况下,有一个合法的角色(通​​常是ÿ,带有DIAERESIS的小拉丁文字母,U + 00FF)会被误解为EOF。
  • char是无符号值。在这种情况下,EOF将被转换为0xFF,然后作为正值提升为int,它将永远不会比较等于EOF,这是一个负值。

无论哪种方式,该计划在某些时候会行为不端。

(或者,更确切地说,曾经是)编译器错误的可能性,使得分配正确发生但分配的值未用于比较。这将导致代码看起来工作正常,即使它不是。幸运的是,这不太可能是现代编译器中的问题。