繁体   English   中英

关于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 但是,当我从标准输入将'ÿ'分配给int c时,事实证明c不等于EOF 这里发生了什么? 2.如果文件中有'ÿ' ÿ”,系统如何区分'ÿ'EOF

'ÿ'是数字 255 的字符表示。它作为字符文字的值是-1

255-1都具有相同的 8 位表示( 11111111 ),这取决于它是被解释为有符号值还是无符号值。 char是有符号的,因此它的值为char-1

当它被分配给一个char变量时,它按原样存储。
当它被分配给一个int变量时,该值被提升为int并且这不会改变它的值,它只是使用更多的位(4 个字节)来表示。

顺便说一句, -1也是EOF的值(但您应该始终在代码中使用常量EOF并且永远不要依赖它的数值)。


getchar()返回一个int 对于'ÿ' ,它返回 255。

当它被分配给一个int时,该值被保留。

当它被分配给char时,行为是未定义的(因为char变量的可能值范围是-128 .. +127 )。
似乎您的编译器选择将255的最右边 8 位存储到char变量中,并且由于char已签名,该值被解释为-1

如果文件中有“ÿ”,系统如何区分“ÿ”和 EOF?

getchar()fgetc() / getc()和其他读取字符的函数返回int 这意味着它们总是在成功时返回(包括) 0255之间的值,而在到达文件末尾时返回EOF (具有负值)。

EOF的值为负数,不能与'ÿ'混淆。

C 程序有一个执行字符集,这决定了字符文字如何映射到 integer 值。

似乎您的程序正在使用 iso-8859-1 作为执行字符集进行编译。 在我的计算机上,gcc 的默认值为 utf-8,其中'ÿ'映射到“多字符常量”50111。使用 iso-8859-1,ZE0D511356BD44123AF49CC91.C9DCF 映射到 - 我必须使用标志-fexec-charset=iso-8859-1来重现您所看到的内容。

当您从文件(或标准输入)读取时,您会得到操作系统给您的任何字节(解释为无符号字符)。 标准输入和文件的编码通常独立于执行字符集。

您观察到的是执行字符集是 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

暂无
暂无

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

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