关于scanf()的缓冲区问题

奇怪的死循环!!

副以下程序:
#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的前面加了一个语句(用来清空键盘输入的缓冲区)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章