关于scanf函数格式说明符%c

一般来讲,我们会用空白字符(空格,换行符和制表符)来使scanf函数读取并返回。但是对于以下代码片段,也就是%c的时候会出现点问题⬇️

char ch[6];
for(int i=0;i<5;i++){
    scanf("%c", &ch[i]);
}
ch[5]='\0';
printf("%s", ch);

    我想输出eeeee,所以输入了e e e e e,但是最后却输出了e e e。为什么呢?

    首先,stdin(标准输入流)是行缓冲。也就是说输入的内容(比如eeeee)在还未按下换行符时是存在缓冲区中,按下后才开始执行I/O操作。

    然后,scanf会读取输入缓冲区中的下一个可用字符。如果缓冲区中没有字符,scanf会等待用户输入。默认情况下,%c会读取任何字符,包括空白字符(如空格、制表符、换行符)。一旦scanf读取了一个字符,无论是空白字符还是有非空白字符,它都会从输入缓冲区中移除这个字符。

    最后,如果%c读取的字符不是所需的最后一个字符,它将留在输入缓冲区中,供后续的scanf调用或其他输入函数使用。

    所以这就是问题的原因。

    想要解决也很简单,在%c前加一个空格⬇️

char ch[6];
for(int i=0;i<5;i++){
    scanf(" %c", &ch[i]);
}
ch[5]='\0';
printf("%s", ch);

scanf会忽略前面的所有空白字符,直到遇见第一个非空白字符。所以在案例中,scanf忽略了e和e之间的空格。

    也可以通过手动把空格“抛走”的方法来防止scanf读取不想要的字符⬇️

char ch[6];
for(int i=0;i<5;i++){
    scanf("%c", &ch[i]);
    getchar();
}
ch[5]='\0';
printf("%s", ch);

    其他时候可以手动刷新缓冲区来防止scanf读取不想要的字符⬇️

void clearstdin() {
    while (getchar() != '\n'); // 读取并丢弃直到换行符
}
或者
fflush(stdin);
但不建议用,因为它并不符合标准,并且在不同的编译器上可能导致不同的行为。
上一篇
下一篇