C - 获取字符问题

C - get character issue

当我运行以下代码时:

#include <stdio.h>
#include <stdlib.h>


int main()
{
    int n;
    char y;

    printf("Message\n");
    fscanf(stdin, "%c", &y);

    printf("Message\n");
    fscanf(stdin, "%c", &y);

    return 0;
}

我明白了:

Message
{enter character}
Message

问题是即使有 2 个 scanf 函数,我也不会被要求输入两次字符。 输出应该是这样的:

Message
{enter character}
Message
{enter character}



我对 getc() 也有这个问题:

#include <stdio.h>
#include <stdlib.h>


int main()
{
    int n;
    char y;

    printf("Message\n");
    y=getc(stdin);

    printf("Message\n");
    y=getc(stdin);

    return 0;
}

此外,fflush() 也没有帮助:

#include <stdio.h>
#include <stdlib.h>


int main()
{
    int n;
    char y;

    printf("Message\n");
    y=getc(stdin);

    fflush(stdin);
    fflush(stdout);

    printf("Message\n");
    y=getc(stdin);

    return 0;
}

我试过 fflush stdin、stdout、stdin+stdout(同时),但结果还是一样。

试试这个:

printf("Message\n");
fscanf(stdin, "%c", &y);

printf("Message\n");
fgetc(stdin); // you need this to consume the \n entered before
fscanf(stdin, "%c", &y);

改变

fscanf(stdin, "%c", &y);

fscanf(stdin, " %c", &y);

引用C11标准:

7.21.6.2 The fscanf function

[...]

  1. A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. The directive never fails.

因此,%c 之前的 space 丢弃了第一个 fscanf 留下的 \n 字符。这个角色是从哪里来的?回想一下,您在输入字符后按 enter 键。这个字符 而不是 被第一个 fscanf 消耗,并保留在标准输入缓冲区 (stdin).

这也发生在程序的第二个版本中,即第二个 getc 得到第一个留下的换行符。您可以使用以下代码刷新(清除)stdin:

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

至于为什么 fflush(stdin); 不起作用是因为标准说行为是未定义的:

7.21.5.2 The fflush function

[...]

  1. If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

但请注意 fflush(stdin) 在某些实现中确实有效。另请阅读 this

此行为的原因是 \n 字符在第一次输入后留在输入缓冲区中。当您按 Enter 时,\n 将与输入字符一起进入缓冲区。您需要删除那个 \n。试试这个

fscanf(stdin, " %c", &y);  

%c之前的space可以跳过任意数量的白色space。

另一种刷新输入缓冲区的方法

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