getchar函数清除while条件之外的输入缓冲区?

时间:2017-07-06 08:29:35

标签: c getchar

我已经知道可以像这样清空输入缓冲区:

while((ch = getchar()) != EOF && ch != '\n');
if (ch == EOF) {
    // oops
}

为什么然后,我不能用一个字符清空缓冲区:

c = getchar();

此行将导致程序等待用户输入。上下文:

void strfuncs()
{
    char name[50] = {0};
    char lastname[50] = {0};
    char c;

    printf("Enter name...:");
    fgets(name, 50, stdin);
    printf("Enter last name...:");
    fgets(lastname, 50, stdin);

    c=getchar();
    printf("Enter a character...:");
    fgets(&c, 1, stdin);

    printf("c: %c",c);
}

2 个答案:

答案 0 :(得分:1)

c = getchar();

如果有缓冲区,则会将缓冲区清空一个字符。但是,考虑到人类相对于计算机运行速度的类型的速度,当该行执行时缓冲区很可能是空的。如果缓冲区为空getchar将等待,直到缓冲区为空。

while((ch = getchar()) != EOF && ch != '\n');

以上情况也不例外。大多数情况下,计算机将在getchar内等待缓冲区变为非空。

在标准输入来自终端的正常模式下,操作系统仅在收到新行字符时才将字符发送到程序的输入缓冲区,或者如果用户强制键入ctrl-D(在*上) nixes,不确定Windows上的等价物是什么)。循环实际上将在第一个getchar()中阻塞,直到您键入整行并按下返回。然后它将尽可能快地围绕循环,消耗你输入的所有字符。 按下返回键后发生这一切。

char c;        // <<<< Wrong!
c = getchar();

这与问题相关,但getchar()的类型为int。这很重要,因为EOF需要区分可以输入的所有有效字符和某些字符集,char的每个可能值(0到255或-128到127)现代通用实现)是一个有效的角色。

答案 1 :(得分:1)

这个用于清空输入流的习惯用法只有在输入流中有要读取的字符时才有效;否则getchar()将阻止,等待输入。如果输入流中有字符,getchar()将读取其中一个字符。

fgets()函数保留换行符,因此看起来没有必要在以这种方式获取输入行之后清理输入流。但是,如果缓冲区不够大,则会留下一些字符。处理此问题的一种方法是检查输入缓冲区是否有换行符,如果输入流不存在则清理输入流。如果在输入缓冲区中找到换行符,则通常会将其删除:

char buffer[1000];

puts("Enter a line:");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
    perror("Error in fgets()");
    exit(EXIT_FAILURE);
}

char *ch;
int c;
if ((ch = strchr(buffer, '\n')) == NULL) {
    while ((c = getchar()) != '\n' && c != EOF) {
        continue;
    }
} else {
    *ch = '\0';
}

请注意,应使用int变量来接收getchar()返回的值,以确保正确处理EOF