繁体   English   中英

fgetc,检查EOF

[英]fgetc, checking EOF

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

fgetc将读取的字符作为unsigned char返回到文件末尾或错误的intEOF 使用fgetc的常见错误是:

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

这段代码的正确版本是:

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

那么,为什么我不能在与EOF比较之前将返回值转换为char 为什么我必须将EOFint进行精确比较? EOF定义为-1 ,它是否通常被转换为char
是否有平台/编译器不适用?

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

通常它是-1但你不应该假设。

c-faq网站上查看这个很棒的答案:

如果在上面的片段中,getchar的返回值被赋值给char,则可能出现两种失败模式。

  1. 如果char类型被签名,并且如果EOF被定义为(通常)为-1,则带有十进制值255(C中的'\\ _377'或'\\ xff')的字符将被符号扩展并将比较等于EOF,过早地终止输入。 (假设8位字符)。

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

希望能帮助到你!

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

“如果你将它转换为char,那么EOF与某个有效字符的值相同,因此与该字符无法区分。仅此一点就足以证明不能使结果成为字符”@FatalError注释。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM