scanf()函数错误把输入缓存里的回车作为一次字符输入

有时我们会需要连续的从标准输入中多次读入数据时,那么就可能存在连续使用多次scanf()函数的情况。然而在连续使用scanf()函数时可能会出现一些难以预料,不易发现的坑

#include <stdio.h>

int main()
{
    char str[20] = { 0 };
    char c = 0;
    scanf("%s", str);
    scanf("%c", &c);
    printf("%s\n", str);
    printf("%c\n", c);
    system("pause");
    return 0;
}
  •  
  • 这里写图片描述

上面的程序原意是要先输入一个字符串,在输入一个字符,但是在输入完成字符串之后,等我们想要再次输入字符时,发现程序已经结束了,这跟我们的设想完全不一样。 
原因是因为scanf()函数会把回车、空格、Tab或一些非法输入的字符当作此次输入的结束标志,它不会把这些字符输入到想要保存此次输入数据的变量中,而是把这些字符遗留在了输入缓冲区,那么,当下一次想要从标准输入中读取一个字符时,这个遗留的字符就正好充当了此次的输入字符。 
显而易见,程序在输入abcdefg之后,输入了回车来结束此次输入,那么回车就遗留在了输入缓冲区,当需要给c输入字符时,它自动的充当了输入的字符,因此,程序没有给我们输入c的字符的机会。(通过输出abcdefg之后又两个空行(残留在输入缓冲区和输出的两个回车导致的)也可以验证)

C语言为了解决这种问题,为我们提供了一种很方便的清空输入缓冲区的方式—->>fflush()函数,它会把残留在输入缓冲区里的所有数据清空,下面是加了程序此函数后的效果。

#include <stdio.h>

int main()
{
    char str[20] = { 0 };
    char c = 0;
    scanf("%s", str);
    fflush(stdin);
    scanf("%c", &c);
    printf("%s\n", str);
    printf("%c\n", c);
    system("pause");
    return 0;
}
  •  

这里写图片描述

很明显的看到此时的字符c是自己需要输入的,fflush(stdin);就是清空输入缓冲区的意思,所以此时的回车被清空,输入缓冲区里面没有任何数据,那么想要获取字符,就得自己输入。

总结

C语言的scanf()函数在接收输入单个字符时会把上一次输入的回车符号当做这次输入的字符,造成无法正确的输入字符数据。这恐怕是初学C的童鞋门遇到的最头疼的问题了。今天给大家提供四种解决方法供借鉴。

  1. 在scanf()中使用'\n'屏蔽回车符号。

    scanf("%d\n",&n); //使用'\n'过滤回车

    scanf("%c",&c);

  2. 在scanf()格式串最前面添加空格,屏蔽回车字符

    scanf("%d",&n);

    scanf(" %c",&c); //%c前面加空格,过滤回车

  3. 在接收字符前,使用getchar()来读取一次回车符号

    scanf("%d",&n);

    getchar();  //专门用来读取上次输入的回车符号

    scanf("%c",&c);

  4. 在接收字符前,使用fflush()清空输入流中缓冲区中的内容

    scanf("%d",&n)

    fflush(stdin);  //清空输入流缓冲区的字符,注意必须引入#include <stdlib.h>头文件

    scanf("%c",&c);

(二)但是前后快两个scanf输入字符串的话就没有enter残留在缓冲区的问题

#include <stdio.h>


int main()
{
char str[20] = { 0 }; char str2[20] = { 0 };
char c = 0;
scanf("%s", str);
scanf("%s", str2);
printf("%s\n", str);
printf("%s\n", str2);

return 0;

}

参考:https://blog.csdn.net/ljx_5489464/article/details/50827697

猜你喜欢

转载自blog.csdn.net/qq_34793133/article/details/80579587