窗口下的 EOF 值

Value of EOF under windows

提问人:うちわ 密か 提问时间:10/3/2017 最后编辑:gsamarasうちわ 密か 更新时间:10/3/2017 访问量:2273

问:

我写了这个代码:

#include <stdio.h>

int main() {
    int c;

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

    return 0;
}

在窗口下,我发现我必须输入 ctrl+z 才能停止程序,我还打印了 EOF 的值,它是 -1。 但是,当我输入 -1 而不是 ctrl+z 时,程序会继续执行,我想了解原因。谢谢!

C Windows EOF

评论

1赞 Stephan Lechner 10/3/2017
您的意思是输入“-1”作为文本,这将产生两个字符值,a 和 a ?'-''1'
0赞 うちわ 密か 10/3/2017
@StephanLechner 是的,就是这样。
0赞 YaatSuka 10/3/2017
使用(或用于浮点数)从atoi()atof()libmath

答:

3赞 Stephan Lechner 10/3/2017 #1

输入为文本不会返回整数值,而是返回两个字符,即 a(对应于 ASCII 值)和 a(对应于 ASCII 值)。两者不等于(以十进制表示)。"-1"-1'-'45'1'49EOF-1

根据定义,您不能输入作为负值使用的内容,因为负值被定义为表示“文件结束”。getchar()

如果要读取整数值(如),请使用:-1scanf

int num;
if (scanf("%d", &num)==1) { // successfully read one valid integral value?
    printf("you entered number %d:", num);
}

评论

0赞 うちわ 密か 10/3/2017
那么如何输入负整数呢?
4赞 Blastfurnace 10/3/2017
@うちわ密か EOF 不是字符,而是文件流的状态。我碰巧作为 EOF 常量报告给您的程序,但它不是您键入的字符。请注意,在 Windows 上,您使用 ctrl-z 发出信号,但在 linux 上,它是 ctrl-d。
0赞 Eryk Sun 10/3/2017
@Blastfurnace具体来说,当 Windows 控制台处于行输入模式时,以 Ctrl+Z 开头的行读取将返回已读取 0 个字节,库和程序将其解释为 EOF。因此,在 Windows 上,您必须键入 Ctrl+Z,Enter,而在 Linux 上,它只是 Ctrl+D 而没有 Enter。此行为不是为替代函数实现的,但它实际上可用于实现更像 Unix 的 Ctrl+D。在更高级别上,C 运行时的标准 I/O 处理从任何文本模式文件(而不仅仅是控制台)读取 Ctrl+Z (“\x1A”) 作为 EOF。ReadFileReadConsole
-1赞 Paul Gibson 10/3/2017 #2

您需要稍微更改一下逻辑:

#include <stdio.h>
int main() {
int c;
int done = 0;

while (!done)
{
    c = getchar();
    if(c != '-')
        putchar(c);
    else
    {
        c = getchar();
        if (c == '1')//this is an EOF
        {
            done = 1; // and probably putchar the EOF
        }
        else
        {
              putchar('-');
              putchar(c);
        }
    }//else
}//while
return 0;

}

评论

1赞 Keith Thompson 10/3/2017
你为什么要这样做?输入不应触发文件结束条件。问题是“为什么它不这样做?”,而不是“我如何让它这样做?”。-1
0赞 Weather Vane 10/3/2017
您正确使用了该类型,但未作为两个单独的字符出现。这就是为什么返回值不是 。intEOFgetcharintchar
0赞 Paul Gibson 10/4/2017
该问题意味着他想输入“-1”并使其行为方式与 ctrl-z 相同。这会让这种情况发生(为什么投反对票?接受的答案也很好,但假设只输入数字。该问题没有描述他们期望的输入类型,因此我认为它主要是文本字符(而不是数字)。如果没有这些信息,任何答案都只是对所需内容的猜测。
0赞 user207421 8/22/2020
不。该问题指出,他想了解为什么 -1 的行为与 ctrl/z 不同。
3赞 Keith Thompson 10/3/2017 #3

该函数返回刚刚输入的字符的数值(被视为 ,因此它永远不会为负数),或者返回指示不再输入的特殊值。getchar()unsigned charEOF

Windows 使用 Control-Z 来触发文件结束条件,这会导致返回值 。但不是字符值;它被专门选择为不能是字符值的值。getchar()EOFEOF

文件末尾是一个条件,而不是一个值。 是数值,但不是字符值;它是返回的值,用于指示输入处于文件结束状态(或错误条件)。EOFgetchar()

(如果要读取整数值(正数或负数),则需要一次读取单个字符,然后计算字符序列表示的整数值。整数值可以作为字符输入,后跟字符 。C 具有各种函数,例如 和 family,可以进行这种转换。-1'-''1'atoi*scanf

评论

0赞 Dúthomhas 10/3/2017
说得好。这才是OP困惑的真正答案。
2赞 user207421 10/3/2017 #4

EOF 不是一个“值”。它是由库定义的哨兵。stdio

Ctrl/z 是击键,它由终端驱动程序解释,并导致它通知流的结束给从中读取的应用程序,这会导致 C 返回零,从而导致返回 EOF。read()getchar()

Unix、Linux 等对应的击键是 Ctrl/d。