scanf()函数错误把输入缓存里的回车作为一次字符输入
2016-03-08 23:43
267 查看
有时我们会需要连续的从标准输入中多次读入数据时,那么就可能存在连续使用多次scanf()函数的情况。然而在连续使用scanf()函数时可能会出现一些难以预料,不易发现的坑
上面的程序原意是要先输入一个字符串,在输入一个字符,但是在输入完成字符串之后,等我们想要再次输入字符时,发现程序已经结束了,这跟我们的设想完全不一样。
原因是因为scanf()函数会把回车、空格、Tab或一些非法输入的字符当作此次输入的结束标志,它不会把这些字符输入到想要保存此次输入数据的变量中,而是把这些字符遗留在了输入缓冲区,那么,当下一次想要从标准输入中读取一个字符时,这个遗留的字符就正好充当了此次的输入字符。
显而易见,程序在输入abcdefg之后,输入了回车来结束此次输入,那么回车就遗留在了输入缓冲区,当需要给c输入字符时,它自动的充当了输入的字符,因此,程序没有给我们输入c的字符的机会。(通过输出abcdefg之后又两个空行(残留在输入缓冲区和输出的两个回车导致的)也可以验证)
C语言为了解决这种问题,为我们提供了一种很方便的清空输入缓冲区的方式—->>fflush()函数,它会把残留在输入缓冲区里的所有数据清空,下面是加了程序此函数后的效果。
很明显的看到此时的字符c是自己需要输入的,fflush(stdin);就是清空输入缓冲区的意思,所以此时的回车被清空,输入缓冲区里面没有任何数据,那么想要获取字符,就得自己输入。
#include <stdio.h> int main() { char str[20] = { 0 }; char c = 0; scanf("%s", str); scanf("%c", &c); printf("%s\n", str); printf("%c\n", c); system("pause"); return 0; }
上面的程序原意是要先输入一个字符串,在输入一个字符,但是在输入完成字符串之后,等我们想要再次输入字符时,发现程序已经结束了,这跟我们的设想完全不一样。
原因是因为scanf()函数会把回车、空格、Tab或一些非法输入的字符当作此次输入的结束标志,它不会把这些字符输入到想要保存此次输入数据的变量中,而是把这些字符遗留在了输入缓冲区,那么,当下一次想要从标准输入中读取一个字符时,这个遗留的字符就正好充当了此次的输入字符。
显而易见,程序在输入abcdefg之后,输入了回车来结束此次输入,那么回车就遗留在了输入缓冲区,当需要给c输入字符时,它自动的充当了输入的字符,因此,程序没有给我们输入c的字符的机会。(通过输出abcdefg之后又两个空行(残留在输入缓冲区和输出的两个回车导致的)也可以验证)
C语言为了解决这种问题,为我们提供了一种很方便的清空输入缓冲区的方式—->>fflush()函数,它会把残留在输入缓冲区里的所有数据清空,下面是加了程序此函数后的效果。
#include <stdio.h> int main() { char str[20] = { 0 }; char c = 0; scanf("%s", str); fflush(stdin); scanf("%c", &c); printf("%s\n", str); printf("%c\n", c); system("pause"); return 0; }
很明显的看到此时的字符c是自己需要输入的,fflush(stdin);就是清空输入缓冲区的意思,所以此时的回车被清空,输入缓冲区里面没有任何数据,那么想要获取字符,就得自己输入。
相关文章推荐
- LightOj1089(求点包含几个线段 + 线段树)
- [everydayNote] 今天脑子不好使
- docker学习笔记6:利用dockerfile创建镜像介绍(生成简单web服务器镜像)
- Dropbox用户数量突破5亿
- Dropbox用户数量突破5亿
- 属性对话框自学笔记
- grep命令和正则表达式用法
- Intent应用详解
- cocos2dx 基础
- ubuntu配置vim为windows下C++编程风格
- Unity3D 5 官方教程:粒子系统 How-Tos
- [实战]HM-Router configuration for TP ROOM
- array和list的排序算法对比(一):快速排序
- Java 模拟Ajax上传文件
- 策略模式
- oracle中一些关于blob字段的操作
- Cucumber测试驱动开发
- DSA 算法
- 如何阅读他人的程序代码[转]
- hihoCoder Floyd算法