关于scanf函数的问题
来源:互联网 发布:东华软件 数据库 语言 编辑:程序博客网 时间:2024/04/30 09:43
前两天写了一个小程序,程序如下:
main()
{
char a;
char b=1 ;
while(b)
{
printf(" please input a char:");
scanf("%c",&a);
if (a==97)
{
b=0;
}
else
{
printf("your char is %d/n",a);
}
}
}
程序中首先提示用户输入一个char,用scanf函数去读取输入的内容并赋值给 char型的变量a,然后判断此char型变量的值,如果是a(注意a的ASCII码是97)则将b置为0,退出循环,否则,则以十进制打印用户输入的内容,然后继续提示用户输入。。。。直到用户输入的是a,则退出。
但经过编译后,运行,发现一个问题。下面是现象:
C:/TC/TC201E/Project>test6
please input a char:10
your char is 49
please input a char:your char is 48
please input a char:your char is 10
please input a char:
解释:首先,我输入了10,程序打印出 your char is 49,然后继续循环让客户输入,但我还没输入,程序又打印出 your char is 48,等样,又打印出your char is 10,然后才等待用户输入。
网上查了查资料,说计算机将用户输入读取到键盘缓冲区内,每次运行scanf("%c",&a) 时,会从键盘缓冲区内读取未读完的数据进行操作,以上面的例子为准,我输入了10,然后敲了回车,键盘缓冲区内会出现三个字符:1、0、回车。那么依次会从键盘缓冲区内读取1、0、回车字符(回车的ASCII码是10),所以导致上面的输出结果。
那么我的疑问就出来了,这个键盘缓冲区是个什么玩意?是在内存还是键盘呢?如何避免键盘缓冲区的问题呢?
这一系列的问题出来后,挨个解决.
在接触到一个新事物时,我的思路是:首先了解他是什么,他有什么用(what )?为什么要用他(why )?我怎么来用他(how )?我什么时候用他(when )。好,按照我的思路,我们进行下去。当然这几项是我从网上及网友口中得到的答案,如果不正确,敬请校正。
首先,what ,键盘缓冲区就是当你按了键以后如果应用程序来不及响应,就先存在缓冲区里,以后应用程序可以来取。
肯定是在内存里,不过不同系统模式下是不一样的。16位实模式下,一般用BIOS的键盘服务,键盘缓冲区在BIOS的数据区里,位于1MB内存的高端。一般是32个字节什么的。Windows和Linux等32位系统,一般有自己的键盘驱动,不再使用BIOS服务。
接着,why ,由于操作系统的机制,我们不得不用到键盘缓冲区,当你一直按着某个键的时候或者程序来不及处理你输入的内容时,会存放到键盘缓冲区中,等CPU的时间轮询到此任务时,继续进行处理。
接着,how ,我们怎么来用他,更准确的说是,我们如何清空键盘缓冲区,避免错误产生。一般用到fflush(stdin); 首先说明的是C语言把所有的外设都会当成一个文件来进行操作,对于键盘,相当于从一个文件写出;对于显示器,相当于从一个文件读取,而stdin是C标准库定义的标准文件之一,它与键盘相关联。我一般把它理解为指向键盘这个“文件”的指针。所以用fflush(stdin)即可清空键盘缓冲区的内容。当然还有其他方法:rewind(stdin); 这两种方法都需要应用头文件stdio.h,目前测试在windows下可行。linux下没试过,明天去公司试试,网上搜下了下,这两种方法在linux不可行,可以用 setbuf(stdin, NULL) 函数。明天测试下。呵呵
最后,when ,很肯定了,当用到scanf的时候需要根据场景清空缓冲区的时候了。呵呵
前两天解决了此问题,今天总结下,呵呵,如果有不对的地方,欢迎各位网友指正。
备注下:rewind(stdin);的作用也就是把“指向键盘(一个文件)的指针从当前位置挪到键盘(一个文件)开头”,相当于抛弃了当前键盘缓冲区中的数据,重新开始输入。虽然并不是真正的把缓冲区里的数据全部清掉,但却起到了清空键盘缓冲区的作用。
-----------------------华丽的分割线-----------------------------------------------------
昨天把键盘缓冲器的问题发到CSDN的坛子里了,大家还是很给力,问题的连接如下:
http://topic.csdn.net/u/20110531/21/f8a5375f-9b00-4f77-9dcb-645234a8841e.html
其中huiguixian 兄弟给出了Linux内存分布的文章 http://blog.csdn.net/huiguixian/archive/2011/05/23/6440279.aspx
以后可能用的到。呵呵,留用了。
- 关于scanf函数的问题
- 关于scanf的问题
- 关于scanf函数debug无法通过的问题
- 关于scanf格式化输入函数的小问题
- 关于vs2013等编译器scanf函数不能使用的问题
- 关于scanf()的缓冲区问题
- 关于scanf()的一个问题
- 关于 scanf 的入门问题
- 关于scanf和&的问题
- 关于scanf的一个问题
- scanf函数的缓冲区问题
- scanf函数的一些问题
- Scanf函数的输入问题
- scanf()函数的bug问题
- 关于Scanf和gets函数的讨论
- 关于scanf函数和printf的总结
- 关于scanf()函数的细节
- 关于scanf()函数的一些点~
- 关于java垃圾回收
- MongoDB 安装&部署
- 好久没写博客了
- Linux串口编程入门
- TOMCAT容器的JAVA连接池配置。
- 关于scanf函数的问题
- Struts1与Struts2的区别(转)
- JNI入门介绍下
- SimpleFramework成功案例及适用领域
- JNI入门介绍(上)
- JNI中jstring类型与c语言中的字符串的转换
- 检视能取代PP吗?
- SimpleFramework的未来发展目标跟计划
- JBoss下布署Spring2.5和Struts2系统