带有 EOF 的 getchar() 未按预期运行

getchar() with EOF not behaving as expected

在通过 K&R 的过程中,我偶然发现了这种意想不到的行为。考虑以下代码:

#include <stdio.h>

#define MAXWLEN         10  /* maximum word length      */
#define MAXHISTWIDTH    10  /* maximum histogram width  */
#define IN              1   /* inside a word            */
#define OUT             0   /* outside a word           */

int main()
{
    int c, i, state;
    int wlen[MAXWLEN];

    for (i = 0; i < MAXWLEN; ++i)
        wlen[i] = 0;

    i = 0;                  /* length of currend word   */
    state = OUT;            /* start outside of words   */
    while ((c = getchar()) != EOF)
    {
        if (c == ' ' || c == '\t' || c == '\n')
        {
            state = OUT;
            if (i > 0 && i < MAXWLEN)
                ++wlen[i];
            i = 0;
        }
        else if (state == OUT)  /* beginning of word */
        {
            state = IN;
            i = 1;
        }
        else                    /* in word */
            ++i;
    }
    ++wlen[i];

    printf("\nwordlen\toccurences\n");
    for (i = 1; i < MAXWLEN; ++i)
    {
        printf("%6d:\t", i);
        if (wlen[i] > MAXHISTWIDTH)
            wlen[i] = MAXHISTWIDTH;
        for (int j = 0; j < wlen[i]; ++j)
            printf("#");
        printf("\n");
    }
}

这会计算给定输入中所有单词的长度,并打印结果的直方图。结果如预期。

但是我必须按 CTRL-D 两次,如果我输入的最后一个字符不是换行命令 (Enter)。我是 运行 我在 zhs 中的程序,用 cc.

编译文件

有人可以解释为什么会发生这种情况,还是我的机器出现错误?

这不是您的程序的行为,而是终端仿真器的行为。

终端仿真器通常逐行缓冲输入并将输入批量发送给程序。如果在行的中间按下,它们中的大多数通常会忽略 Ctrl-D,只有当你按下它两次时才会检测到它。也许他们将其视为中断缓冲的信号,但不确定它是否存在。