问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
你好,欢迎来到懂视!登录注册
当前位置: 首页 - 正文

为啥scanf清除键盘缓冲区失败

发布网友 发布时间:2022-04-29 21:41

我来回答

1个回答

热心网友 时间:2022-06-23 12:05

你首先要明白,从键盘读入键盘缓冲区(buffer)的数据都是以ASCII码存储的(包括回车)。
程序1
#include "stdio.h"

void main()
{
char a;
char b;
scanf("%d",&a);
scanf("%d",&b);
printf("%d %d",a,b);
}

键盘输入
97<回车>
第一次回车后,buffer中的ASCII:39h,37h,0AH(0A是换行的ASCII), scanf会根据格式字符串中的第一个%d对buffer按字节顺序读取,当读取到0A时,认为%d型的数据结束,此时把已经读取到的39h,37h依据%d转为整型数据97存储在字符型变量a中。(这里是除去了扫描截止点0AH)
此时buffer中已经无任何数据了。

96<回车>
第二次回车后,按同样的流程,scanf会根据格式字符串中的第二个%d对buffer按字节顺序读取。最终b得到96.
此时buffer中已经无任何数据了。
输出
97 96

程序2
#include "stdio.h"

void main()
{
char a;
char b;
scanf("%c",&a);
scanf("%c",&b);
printf("%d %d",a,b);
}

键盘输入
9<回车>buffer:39H,0AH
因为scanf会按照第一个%c格式扫描buffer(只扫描一个字节就结束),然后把扫描到的39H直接送到变量a(当以%d格式读出来时,39H就是57)
此时,buffer中只有:0AH。
然后,scanft又遇到第二个%c,继续扫描buffer,得到0aH并送入变量b.
此时buffer中已经无任何数据了

输出
57 10

程序3
#include "stdio.h"

void main()
{
char a[100];
char b[100];
scanf("%s",a);
scanf("%s",b);
printf("%s %s",a,b);
}

键盘输入
abc<回车>
第一次回车后,buffer:61H,62H,63H,0AH。
scanf会按照%s的格式对buffer按字节顺序扫描,当扫描到0AH时,结束扫描(按照%s的要求,空格20H也是扫描结束点)。
然后把扫描到的(除去最后一个判断扫描截至的字节0AH)数据直接送入以a为起始地址的字符串。
此时,buffer无任何数据了。

def<回车>
第二次回车后,buffer:65H,66H,67H,0AH.扫描的流程与上面的完全一致。
输出
abc def

程序4
#include <stdio.h>
void main()
{
int i;
char j;
for(i=0;i<2;i++)
scanf("%c",&j);/*注意这里%前没有空格*/
printf("%d",j);
}

键盘输入
1<回车>,
这里scanf执行了两次(i==0时,与i==1时),而且每次都是想对j赋值。
第一次scanf,按%c的要求,只扫描buffer中的一个字节,但是buffer中并不数据,于是要求键盘输入数据到buffer,此时的1<回车>代表向buffer中输入了:31H,0AH。
然后按%c的要求,只扫描buffer中的一个字节:31h,并将它直接送入变量j.
此时,buffer中还留下:0AH。

第二次scanf要求键盘输入数据,按%c的要求,只扫描buffer中的一个字节:0Ah,并将它直接送入变量j.
此时,buffer无数据了。

最后,你用%d格式输出j的值(0AH换成整型就是10)

输出
10

程序5
#include <stdio.h>
void main()
{
int i;
char j;
for(i=0;i<2;i++)
scanf(" %c",&j);/*注意这里%前有一个空格*/
printf("%d",j);
}
1<回车>2<enter>的情况:
scanf会按照格式控制字符串的要求,顺序扫描buffer.
但是你其中有一个空格,这个很特殊,我也是第一次发现这个问题(一般我都不会在scanf中加入任何常量字符)

我测试了一下:我发现这个空格有吸收回车(0AH)和空格(20H)的“神奇功效”,吸收之后再要求buffer给一个字节,直到这个字节不是0AH或者 20H,此时把这个字节交给下一个格式字串。

第一次循环时遇到格式字串空格,就扫描buffer中的一个字节,但是buffer中无数据,要求从键盘输入数据:1〈回车〉,buffer中有数据了——31H,0AH。再读取到字节31H,scanf发现这个并不是0AH/20H,就把这个字节31H交给格式字符%c处理。
循环结束,此时buffer里面还有:0AH.

第二次循环时遇到格式字串空格,就扫描buffer中的一个字节——0AH,发现是0AH/20H,于是就要求buffer再来一个字节。此时buffer里面已经没有数据了,要求键盘输入:2<enter>.
buffer中有数据了——32H,0AH。于是再读一个字节31H,scanf发现这个并不是0AH/20H,就把这个字节32H交给格式字符%c处理(j最终得到32H)。
循环结束,此时buffer里面还有:0AH.
声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com
用手柄玩实况足球2012, 实况足球12如何进行手柄设置,以及窗口模式的设置? 带娃去感受乡村的夏天,这53条乡村游线要收藏好 一般签名用什么笔 怎么去追女孩的技巧 清朝有多少汉人被封王 《水滴石穿》告诉我们什么道理 重庆有哪些批发市场 重庆有哪些大型市场 重庆最大零食批发市场 大众朗行点烟器电压是多少 写三篇社会实践体会,最少400字 大众桑塔纳点烟器怎么用,桑塔纳点烟器保险丝位置? c语言,scanf函数,在输入一个数据时,如何使数据进去缓冲区? 法系特有的倔强!150cc通勤踏板,虽然亮点颇多,但这价格…… 大众朗逸点烟器没有电怎么办? 关于有意义的社会实践活动的日记3篇 初中日记 大众朗逸车点烟器如何使用 高颜值运动踏板,配水冷引擎,12.6匹马力,操控性好,15500元 烟台地区一汽大众探岳优惠4万元 清空输入缓冲区是什么意思 有什么用 机箱风扇线正负极线是什么颜色的 探岳280有220伏电源接口吗? 踏板摩托车哪个品牌好?豪爵铃木,建设雅马哈,五羊本田这几个品牌怎么选? 标致“贵族”通勤踏板,单缸水冷四冲程,功率9.3kw配abs,2.28万 途岳的点烟器拔出来为什么是空的 大众探岳室内天花扶手怎样拆 宁波市瞻岐人饭店(万兴路店)怎么样?有什么好玩的地方? c语言清除缓冲区的数据? 虾潺能放冷冻室吗 安娜苏魔镜香水价格 宁波话里有种鱼叫haodie 学名叫什么? scanf(&quot;%d%d&quot;,&a,&b)与scanf(&quot;%d,%d&quot;,&a,&b)的区别!! 三篇小学生社会实践日记300字 c语言中用了scanf语句就输不出结果把scanf删掉就能出结果是为啥 安室奈美惠和滨崎步在日本谁更红? 急求社会实践日记??? 还是我,为什么这个没有清空缓冲区,但是scanf语句没有被跳过呢? 售价2.38w,标致发布姜戈CLUB限量版,提供丰富增值项目 在输入数据类型和字符类型的两个scanf函数调用之间使用什么库函数以清除键盘缓冲区的字符? 机箱风扇线正负极? 求 社会实践活动作文200字(4篇),不要关于工作的,谢谢了! 云南昭通市盐津县有多少乡镇,各乡镇有多少人口 C语言中scanf和getchar问题一例。必有重谢. 社会实践活动日记 C语言中gets()函数和清空缓冲区问问题 社会实践活动的作文 贵广高速铁路的贵广高铁沿途站点及市县 龙头鱼要怎么做好吃 文明礼仪我传递,社会实践活动日记
  • 焦点

最新推荐

猜你喜欢

热门推荐