【转】关于scanf()的缓冲区问题

昨天去南汇带学生的数据结构上机,好累,看到满眼的c,满脑的指针,结构体。头大的不得了!学生的问题也爆怪!遇到两个问题,虽现在都已经解决,但还是决定放在这里,供以后使用!(发现c语言真的是博大精深,自己还是欠缺很多!)对了,前天的uclinux也成功装上去了,不容易啊!

奇怪的死循环!!

副以下程序:
#include
main()
{int i;
do{
printf("*");
scanf("%d",&i);
}while(1);
}
这个程序非常的简单.粗看上去没有什么,功能就是每打印一个星号后等待用户输入一个整形得值,但问题接种而来,用户一但输入的是数字外的各种字符,立刻造成死循环.单步执行也无法跳出.但作为scanf这样的控制流函数,无论我的输入是否正确,他都应在下一次执行时停住等待用户输入,但问题是它自动执行了. 为此我做过变量的值跟踪,发现每次他能自动获得一个值.且这个值并不是整形量且无序改变.在换了BC编译以后问题消失.但是当单步执行后问题依旧出现.

当输入字符的时候,把i的内容输出来。
可以得知 i的值一直保持不变。(且跳过了scanf函数)。
对于scanf()函数可以想象引发一个中断响应。(引出中断相应表明一点就是此函数调用了中断----------等待输入的中断)
产生这个响应可能需要一个条件,那就是此函数所开辟或者说是为中断开辟的缓冲区应是空的!
因此出现这种错误的原因可能是缓冲区没清空。
以‘/n'表示输入结束(这个说的有不小问题我想,不过为表示一下这么说的)
然后编译系统自动在后面加上清空标志^Z(ctl+z),以为下一次调用。
至于输入字符就陷入跳过这个语句,可能是因为当初设计这个函数的时候没有对异常做充分的处理,以至于在读入第一个字符的时候发现类型不匹配就停止把他后面的清空标志^Z传递到缓冲区域了。(前面可能说的有点问题,应该说是scan)
在执行scanf时候检查缓冲区是否为空,为空的时候执行,否则不执行(在前一次执行scanf函数的时候没有把缓冲区清空)。
在进行负值的时候出现类型错误,跳转了语句。没有执行清空语句。(后面所有的scanf语句都不起作用了,包括子程序中的);
整个main程序结束后才清空;
呵呵~~~~~~
乱想着说的!~最近在看汇编和C++就乱讲了一点,呵呵!~C++中也经常把cout的优点和scanf的缺点搞出来讲!但具体为什么会这样
我想要追究到编译软件上面,因为scanf()不是c 的语句而是编译软件接受标准定的一个同名的输入函数 标准就体现在用相同的名字(也就是声明部分一样)。但至于scanf()函数的定义体一不一样,那就不得而知了!~

不过好象不是这个概念。。。是要维持整形输入不变。。。这样的改变不是从实质上解决问题而围绕了个弯逃避问题。。。SCANF是有缓冲的一个输入语句。不像GETCHAR那样能直接获得一个值。。但问题就处在这个输入缓冲区了。。它里面值并没有被处理掉。当然这个是我通过值跟踪后和我的导师讨论出来的结果。。。。。我是想问一下谁能有经验的话分析一下这个问题的真正错误在什么地方。。如何解决。。我初步觉得应该用汇编。。但是具体的分析和逻辑上还有点乱。。

解决方法:fflush(stdin);在scanf的前面加了一个语句(用来清空键盘输入的缓冲区)

scanf输入缓冲区问题是指在使用scanf函数进行输入时,输入缓冲区中可能会残留上一次输入的换行符\n,导致下一次输入不符合预期。例如,当我们输入完1 2后按下回车键,输入缓冲区里存放着1 2 \n。第一次scanf读走1给a,2给b,中间的空格丢弃,此时第一句scanf已经读完。但是缓冲区里还留着一个\n,当第二次scanf读入时,首先检查缓冲区,发现缓冲区里还有\n,而且正好匹配%c,于是直接读走\n给c。这就是典型的scanf缓冲区问题。 为了解决scanf输入缓冲区问题,可以使用以下方法: 1. 使用fflush(stdin)命令强行刷新输入缓冲,丢弃输入缓冲中的数据。这个方法可以清除缓冲区中的换行符等残留数据,确保输入的正确性。 2. 使用getchar()函数吃掉前面的回车确认符。在执行读取字符操作之前,使用getchar()读取并丢弃缓冲区中的回车符,确保下一次输入的正确性。 3. 使用rewind(stdin)清除标准输入的按键缓冲区。rewind函数是把指定流的读写指针重新指向开头,可以清除输入缓冲区中的残留数据。 通过使用上述方法,可以有效地解决scanf输入缓冲区问题,确保输入的准确性和一致性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [scanf缓冲区问题](https://blog.csdn.net/qq_45908718/article/details/117394732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值