使用scanf函数时有时会把回车也读入,最终让回车传入缓冲区

 用scanf输入字符时可能就会出现这样的问题(只输入数字则不会)。。。

一般情况下,这种问题会出现在%d与%c搭配的情况下。例如:

scanf("%d",&a);

scanf("%c",&b);//变量已提前声明

printf("%d %c",a,b);

大家可以自己运行看看,输出结果a正常是数字,而b什么都没有。在这种情况下同时读入一串数字以及回车时,系统将其全部保存进缓冲队列,并且与%d的格式的a和%c格式的b一一匹配。a得到数字,b得到字符回车。

这是因为,一般情况下,如果你使用从输入流缓冲区中读取数据的函数(scanf或者getchar),系统会把从键盘输入的字符先放入缓冲队列(注意,别误会,不管有没有使用从输入流读取数据的函数,系统都会把数据先输入缓冲区,这里只是为了强调不是直接从stdin键盘缓冲区读取),直到键入回车键或者遇到文件结束符EOF时,再从输入缓冲区逐个读取字符。

因此输入的时候可以换一些别的方法。

一、scanf("%c%*c",&a);

1,用%*c读入多余的回车符。也可以节省空间。

2,在%c前面加上一个空格,这样scanf可以忽略对空格的读取。如scanf(" %c",a); 这个办法也非常有效。


二、gets();

//开玩笑的,太危险了,还是算了吧,用fgets。

if (fgets(number,SHU_ZI_CHANG_DU, stdin) == NULL) 

    {

       return FALSE;

    }

    length =strlen(number) - 1;

    if (number[length]== '\n') 

    {

       number[length] = '\0';

    }

用fgets输入数据,安全得多。这样子,直接把最后的回车转化为字符串的结束符。​


三、getchar();

在scanf("%c",a);后面使用一个getchar(),就可以把刚刚得到的回车符放进去。​

但是可能引来别的坑。如果你使用了行输入函数getchar(),一行输入结束后,getchar()才开始从输入缓冲队列读取字符,没被读走的会留在缓冲区队列,等待下一次读取。这里有个例子:

ch1 = getchar();

printf("ch1 = %c\n",ch1);

ch2 = getchar();

printf("ch2 = %c\n",ch2);//字符变量已经提前声明

当输入a再回车,print出来的只有一个a;

当输入ab再回车,print出来的是一个a和一个b。

所以使用getchar()也可能会出现类似的问题,所以要与scanf搭配着使用来读取回车符(推荐用法)。如:

scanf("%c",&a);

getchar();//得到回车符


四 刷新缓冲队列

fflush(stdin);


最终总结,fgets()还是比较不错的,尽量使用fgets吧!

猜你喜欢

转载自blog.csdn.net/qq_43499599/article/details/87736093