关于 EOF 和 ÿ 的困惑
Confusion about EOF and ÿ
在我的 Windows 上的 GCC 中,EOF
的值是 -1
。我注意到 'ÿ'
的值也是 -1
。所以我做了以下实验,但我对结果完全感到困惑。
int main() {
int a = 'ÿ';
if (a == EOF) {
putchar('a');
putchar(a);
}
char b = 'ÿ';
if (b == EOF) {
putchar('b');
putchar(b);
}
putchar('\n');
int c;
if ((c = getchar()) != EOF) {
putchar('c');
putchar(c);
}
char d;
if ((d = getchar()) != EOF) {
putchar('d');
putchar(d);
}
}
结果是
aÿbÿ // a == EOF b == EOF
ÿÿ //My input for int c and char d
cÿ // c != EOF
我的问题是:
1. 当我直接将'ÿ'
赋值给一个变量时,无论类型是int还是char,都等于EOF
。但是当我从 stdin 将 'ÿ'
分配给 int c
时,结果发现 c
不等于 EOF
。这里发生了什么?
2.如果文件中有'ÿ'
,系统如何区分'ÿ'
和EOF
?
'ÿ'
是数字 255 的字符表示。它的值为 char literal 是 -1
.
255
和-1
都具有相同的8位表示(11111111
),这取决于它是被解释为有符号值还是无符号值。 char
是有符号的,因此它作为 char
的值是 -1
.
当它被分配给一个 char
变量时,它按原样存储。
当它被分配给一个 int
变量时,该值被提升为 int
并且这不会改变它的值,它只是使用更多的位(4 个字节)来表示。
顺便说一句,-1
也是EOF
的值(但你应该在代码中始终使用常量EOF
,不要依赖它的数值)。
getchar()
return一个int
;对于 'ÿ'
它 returns 255.
当它被分配给一个 int
时,值被保留。
当它分配给 char
时,行为未定义(因为 char
变量的可能值范围是 -128
..+127
) .
似乎您的编译器选择将 255
最右边的 8 位存储到 char
变量中,并且由于 char
已签名,该值被解释为 -1
.
How does the system distinguish between 'ÿ' and EOF if there's a 'ÿ' in the file?
getchar()
、fgetc()
/getc()
等读取字符的函数returnint
。这意味着当成功时它们总是 return 值介于(包括)0
和 255
之间,当到达文件末尾时它们总是 EOF
(具有负值)。
EOF
的值为负数,不能与'ÿ'
混淆。
C 程序有一个执行字符集,这决定了字符文字如何映射到整数值。
您的程序似乎正在使用 iso-8859-1 作为执行字符集进行编译。在我的电脑上,gcc 的默认值是 utf-8,其中 'ÿ'
映射到“多字符常量”50111。对于 iso-8859-1,gcc 将其映射到 -1。我必须使用标志 -fexec-charset=iso-8859-1
来重现您所看到的内容。
当您从文件(或标准输入)中读取时,您将获得操作系统提供给您的任何字节(解释为无符号字符)。 stdin 和文件的编码通常独立于执行字符集。
您观察到的是执行字符集是 iso-8859-1 映射到范围 -128 到 127(而不是通常的 0 到 255),大概是因为 char
在您的编译器上签名,因此可以表示执行字符集中的每个值。 stdin 的编码似乎也是 iso-8859-1,除了它使用通常的 0 到 255。在你的问题中的情况 (d) 中,值 255 被分配给 char
(可能已签名, 从 -128 到 127), gcc 正在包装它。
总结:
- (a) 将 -1 分配给
a
- (b) 将 -1 分配给
b
- (c) 将 255 分配给
c
- (d) 将 255 转换为
char
,结果为 -1。这个 -1 赋值给 d
.
在我的 Windows 上的 GCC 中,EOF
的值是 -1
。我注意到 'ÿ'
的值也是 -1
。所以我做了以下实验,但我对结果完全感到困惑。
int main() {
int a = 'ÿ';
if (a == EOF) {
putchar('a');
putchar(a);
}
char b = 'ÿ';
if (b == EOF) {
putchar('b');
putchar(b);
}
putchar('\n');
int c;
if ((c = getchar()) != EOF) {
putchar('c');
putchar(c);
}
char d;
if ((d = getchar()) != EOF) {
putchar('d');
putchar(d);
}
}
结果是
aÿbÿ // a == EOF b == EOF
ÿÿ //My input for int c and char d
cÿ // c != EOF
我的问题是:
1. 当我直接将'ÿ'
赋值给一个变量时,无论类型是int还是char,都等于EOF
。但是当我从 stdin 将 'ÿ'
分配给 int c
时,结果发现 c
不等于 EOF
。这里发生了什么?
2.如果文件中有'ÿ'
,系统如何区分'ÿ'
和EOF
?
'ÿ'
是数字 255 的字符表示。它的值为 char literal 是 -1
.
255
和-1
都具有相同的8位表示(11111111
),这取决于它是被解释为有符号值还是无符号值。 char
是有符号的,因此它作为 char
的值是 -1
.
当它被分配给一个 char
变量时,它按原样存储。
当它被分配给一个 int
变量时,该值被提升为 int
并且这不会改变它的值,它只是使用更多的位(4 个字节)来表示。
顺便说一句,-1
也是EOF
的值(但你应该在代码中始终使用常量EOF
,不要依赖它的数值)。
getchar()
return一个int
;对于 'ÿ'
它 returns 255.
当它被分配给一个 int
时,值被保留。
当它分配给 char
时,行为未定义(因为 char
变量的可能值范围是 -128
..+127
) .
似乎您的编译器选择将 255
最右边的 8 位存储到 char
变量中,并且由于 char
已签名,该值被解释为 -1
.
How does the system distinguish between 'ÿ' and EOF if there's a 'ÿ' in the file?
getchar()
、fgetc()
/getc()
等读取字符的函数returnint
。这意味着当成功时它们总是 return 值介于(包括)0
和 255
之间,当到达文件末尾时它们总是 EOF
(具有负值)。
EOF
的值为负数,不能与'ÿ'
混淆。
C 程序有一个执行字符集,这决定了字符文字如何映射到整数值。
您的程序似乎正在使用 iso-8859-1 作为执行字符集进行编译。在我的电脑上,gcc 的默认值是 utf-8,其中 'ÿ'
映射到“多字符常量”50111。对于 iso-8859-1,gcc 将其映射到 -1。我必须使用标志 -fexec-charset=iso-8859-1
来重现您所看到的内容。
当您从文件(或标准输入)中读取时,您将获得操作系统提供给您的任何字节(解释为无符号字符)。 stdin 和文件的编码通常独立于执行字符集。
您观察到的是执行字符集是 iso-8859-1 映射到范围 -128 到 127(而不是通常的 0 到 255),大概是因为 char
在您的编译器上签名,因此可以表示执行字符集中的每个值。 stdin 的编码似乎也是 iso-8859-1,除了它使用通常的 0 到 255。在你的问题中的情况 (d) 中,值 255 被分配给 char
(可能已签名, 从 -128 到 127), gcc 正在包装它。
总结:
- (a) 将 -1 分配给
a
- (b) 将 -1 分配给
b
- (c) 将 255 分配给
c
- (d) 将 255 转换为
char
,结果为 -1。这个 -1 赋值给d
.