EOF象征性常数

时间:2013-10-31 20:17:53

标签: c eof

来自 C编程语言

int c;
while ((c = getchar()) != EOF)
    putchar(c);

“......解决方案是getchar在没有更多输入时返回一个独特的值,这个值不能与任何真实字符混淆。这个值称为EOF,用于”文件结尾。“我们必须声明c是一个足以容纳getchar返回的任何值的类型。我们无法使用char,因为c必须很大足以容纳EOF以及任何可能的char。“

我检查了stdio.h并在我的系统上打印了EOF的值,并将其设置为-1。在我的系统上,chars已签名,但我知道这取决于系统。因此,EOF可以适合我的系统char。我通过将c定义为char来重写上面的小例程,程序按预期工作。 ASCII字符表here中还有一个字符,其中一个空格字符对应于255,其行为类似于EOF

那么,为什么看起来ASCII有一个为EOF指定的字符(255)?这似乎与 The C Programming Language 一书中的内容相矛盾。

5 个答案:

答案 0 :(得分:5)

getchar()读取字节255时,它返回255.当getchar()发现没有更多输入时,它返回-1。

如果将结果存储在char中,则无法区分这两者。但是当你将它们存储在int中时,你可以。 (此声明独立于char)的签名。

只有当知道结果有效时才能将其转换为char并获得通常的C风格字符类型。

答案 1 :(得分:3)

  

那么,为什么看起来ASCII有一个为EOF指定的字符(255)?

没有。更准确地说,这不是EOF“角色”。

诀窍是,getchar()如果有东西要读,将始终返回非负值。如果它遇到文件结尾,它将只返回-1(这是EOF似乎在您的实现上定义的内容。)

char是:

  1. 8位宽,
  2. 签名并
  3. 使用2的补码表示,
  4. 只是你实施的一个怪癖(尽管现在绝大多数都是常见的)。因此,如果您使用char来存储getchar()的返回值,那么读取输入可能会提前终止:代码为255的字符将被误认为-1 a。 ķ。一个。 EOF这是一个错误。这就是发生在你身上的事。 它不起作用 - 相反,你的第二种方法完全被打破了。

答案 2 :(得分:3)

根据getchar()手册,它总是返回int值:

#include <stdio.h>
...
int getchar(void);
...
RETURN VALUE
fgetc(), getc() and getchar() return the character read as 
an unsigned char cast to an int or EOF on end of file or error.

因此使用char而不是int将导致截断(int -1(0xffffffff)变为char -1(0xff))并可能导致错误。

答案 3 :(得分:2)

要理解这是如何工作的,想象那个写getchar思维的人是什么。你需要读一个文件。首先创建一个例程 - 例如:

unsigned char get_me_a_byte(file)... // 0..255

现在要读取文件中的所有字节:

unsigned char c;

while( c = get_me_a_byte(file) ) // while( (c = get_me_a_byte(file)) != 0 )
{
  ... do sth
}

问题是当遇到z零时它会停止但是你想在一切都是红色时停止。 现在你变得更聪明 - 你知道文件可以被认为是字节序列。 如果 get_me_a_byte 可以返回16位或32位类型怎么办?然后你可以使用一些字节不能作为文件结束标记的值。

宾果

由于您的决定权属于您,您可能会:

int get_me_a byte_U(file) ... // returning bytes as 0..255
int get_me_a byte_S(file) ... // returning bytes as -128..127

现在你可以做到:

int c;
while( (c = get_me_a_byte_U(file) != UUU ) ....

其中 UUU 可以是您平台上256到MAXINT的任何内容

同样:

int c;
while( (c = get_me_a_byte_S(file) != SSS ) ....

其中 SSS 可以是任何来自MININT ..- 129和128..MAXINT

现在,如果您选择第一种方法,则有一个问题:UUU(您的EOF)的价值应该是什么?

( - 1)对EOF有好处,因为无论你将它分配给变量的位宽是多少,它都将保持为(-1)。通过'保持-1',我的意思是它将始终是所有模式。

char c = -1; // c = 11111111b / 0xFF / 255 (assuming your char is signed 8bit)
short s = -1; // s = 1111111111111111b / 0xFFFF / 65535
int i = -1; // s = 11111111111111111111111111111111b / 0xFFFFFFFF / 4294967295

现在应该是显而易见的。

答案 4 :(得分:1)

没有矛盾。

  • EOF不是一个字符,只是读取文件时发现的一个条件。
  • ASCII 255有时对应于不间断的空间a.k.a HTML实体&nbsp;

如评论中所述,ASCII只编码128个字符,除此之外你会发现不同的编码。

从您链接到的表格我会说:

  

255是不可打印的字符