来自 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 一书中的内容相矛盾。
答案 0 :(得分:5)
当getchar()
读取字节255时,它返回255.当getchar()
发现没有更多输入时,它返回-1。
如果将结果存储在char
中,则无法区分这两者。但是当你将它们存储在int
中时,你可以。 (此声明独立于char
)的签名。
只有当知道结果有效时才能将其转换为char
并获得通常的C风格字符类型。
答案 1 :(得分:3)
那么,为什么看起来ASCII有一个为EOF指定的字符(255)?
没有。更准确地说,这不是EOF“角色”。
诀窍是,getchar()
如果有东西要读,将始终返回非负值。如果它遇到文件结尾,它将只返回-1
(这是EOF
似乎在您的实现上定义的内容。)
char
是:
只是你实施的一个怪癖(尽管现在绝大多数都是常见的)。因此,如果您使用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)
没有矛盾。
如评论中所述,ASCII只编码128个字符,除此之外你会发现不同的编码。
从您链接到的表格我会说:
255是不可打印的字符