简体   繁体   English

fgetc,检查EOF

[英]fgetc, checking EOF

In the book Linux System Programming I have read some like this: Linux系统编程一书中,我读过这样的文章:

fgetc returns the character read as an unsigned char cast to an int or EOF on end of file or error. fgetc将读取的字符作为unsigned char返回到文件末尾或错误的intEOF A common error using fgetc is: 使用fgetc的常见错误是:

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

The right version of this code is: 这段代码的正确版本是:

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

So, why can't I cast a return value to char before comparing with EOF ? 那么,为什么我不能在与EOF比较之前将返回值转换为char Why do I have to compare EOF exactly with int ? 为什么我必须将EOFint进行精确比较? As EOF defined as -1 , isn't it normally casted to char ? EOF定义为-1 ,它是否通常被转换为char
Are there platforms/compilers where it is not true? 是否有平台/编译器不适用?

You can't cast the return value to char because the return value could be EOF , and EOF value is system-dependent and is unequal to any valid character code. 您不能将返回值强制转换为char,因为返回值可能是EOF ,并且EOF值是系统相关的,并且不等于任何有效的字符代码。 link 链接

Usually it is -1 but you should not assume that. 通常它是-1但你不应该假设。

Check this great answer from the c-faq-site : c-faq网站上查看这个很棒的答案:

Two failure modes are possible if, as in the fragment above, getchar's return value is assigned to a char. 如果在上面的片段中,getchar的返回值被赋值给char,则可能出现两种失败模式。

  1. If type char is signed, and if EOF is defined (as is usual) as -1, the character with the decimal value 255 ('\\377' or '\\xff' in C) will be sign-extended and will compare equal to EOF, prematurely terminating the input. 如果char类型被签名,并且如果EOF被定义为(通常)为-1,则带有十进制值255(C中的'\\ _377'或'\\ xff')的字符将被符号扩展并将比较等于EOF,过早地终止输入。 (assuming 8 bits char). (假设8位字符)。

  2. If type char is unsigned, an actual EOF value will be truncated (by having its higher-order bits discarded, probably resulting in 255 or 0xff) and will not be recognized as EOF, resulting in effectively infinite input. 如果char类型是无符号的,则实际的EOF值将被截断(通过丢弃其高阶位,可能导致255或0xff)并且不会被识别为EOF,从而导致无限输入。

Hope it helps! 希望能帮助到你!

Edited: (added the @FatalError comment on this answer, this is explained on the c-faq site but this looks more clear to me) 编辑:(在这个答案中添加@FatalError评论,这在c-faq网站上有解释,但这对我来说更清楚)

"If you cast it to char then EOF takes the same value as some valid character and hence becomes indistinguishable from that character. That alone should be enough justification to not make the result a char" @FatalError comment. “如果你将它转换为char,那么EOF与某个有效字符的值相同,因此与该字符无法区分。仅此一点就足以证明不能使结果成为字符”@FatalError注释。

There are two possibilities when you assign the value to a char before comparing with EOF: 在与EOF比较之前将值分配给char时有两种可能性:

  • char is a signed value. char是一个有符号的值。 In that case, there is a legitimate character (often ÿ, SMALL LATIN LETTER Y WITH DIAERESIS, U+00FF) that will be misinterpreted as EOF. 在这种情况下,有一个合法的角色(通​​常是ÿ,带有DIAERESIS的小拉丁文字母,U + 00FF)会被误解为EOF。
  • char is an unsigned value. char是无符号值。 In that case, EOF will be translated to 0xFF, and then promoted to int as a positive value, which will never compare equal to EOF which is a negative value. 在这种情况下,EOF将被转换为0xFF,然后作为正值提升为int ,它将永远不会比较等于EOF,这是一个负值。

Either way, the program is going to misbehave some of the time. 无论哪种方式,该计划将在某些时候行为不端。

There is (or, more accurately, used to be) a chance of a compiler bug such that the assignment occurred correctly but the assigned value was not used for the comparison. (或者,更确切地说,曾经是)编译器错误的机会,使得分配正确发生但分配的值不用于比较。 That would lead to the code appearing to work OK even when it is not. 这将导致代码看起来工作正常,即使它不是。 Fortunately, that is unlikely to be a problem found in a modern compiler. 幸运的是,这不太可能是现代编译器中的问题。

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

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