编程的时候,我们有时候需要清空留在输入缓存区里面的一些我们不想要的数据。
通常我们遇到的问题是:程序在运行过程中会要求输入多次,然而首次输入后,在需要第二次输入的时候,我们没有输入程序就自动执行下去了。在 C 和 C++中,即使是输入时类型匹配,也有可能会发生这种情况。譬如在输入 char 类型的数据时,我们输入一个字符后回车,第二次输入时就被程序跳过了。另外就是在输入的数据类型与要求的类型不匹配时,并且不能按照语言中默认可以自动转换的顺序予以转换,则会发生同样问题。
先看几种易发生错误的写法:
1、读取换行符跳过输入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <stdio.h> #include <stdlib.h> int main() { int inputA, inputB; printf("Input the first number(char):\n"); scanf("%c", &inputA); printf("inputA = %d.\n", inputA); printf("Input the second number(char):\n"); scanf("%c", &inputB); printf("inputB = %d.\n", inputB); getchar(); return 0; } |
运行时错误如下图:

2、类型不匹配时读取其它字符跳过输入:
程序要求输入int型,输入时不小心输入了字符,如下图所示:

发生这类情况的原因是我们键盘键入的数据会保存在输入流中,而不是直接送给被赋值的变量。这样,当要求连续两次输入时,如果第一次的输入只读取了输入流的一部分,第二次输入时程序还能从输入流中读出东西,就会跳过让我们从键盘给值的过程。如上面所说第一种情况中第二次输入时就读取了一个回车符。
到目前为止,标准C/C++还没有能保证清空这一输入缓存区的函数,但是我们可以通过一些函数(C++习惯叫方法)的组合来解决这一问题。下面是几种方法,它们基本可以保证成功清空缓存区,并且在缓存区没有需要清除的数据时也能正常工作。这几种方法对于类型不匹配从而产生的输入错误,它们也能侦测到错误,并要求重新输入。其中用以清空缓冲区的部分包含在里面,有注释。我把它们按 C语言和C++区分开来。
一、C语言Linux && Windows平台:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <stdio.h> int main() { int inputA, inputB; int flag = 1; /*标记是否输入类型匹配要求*/ printf("Input the first number(int):\n"); flag = scanf("%d", &inputA); /*scanf获得的值类型不匹配时返回0.*/ /*如果输入类型不匹配,或者输入中含有非法字符时要求重输.第一次输入错时会要求继续按一个回车,第二次则不再需要.*/ while(flag == 0 || getchar() != '\n') { setbuf(stdin, NULL); /* Linux系统中用以清空缓冲区的函数.*/ while (getchar() != '\n'); /*循环读取缓冲区中的字符*/ printf("Input type error,please enter again: "); flag = scanf("%d", &inputA); } printf("inputA = %d.\n", inputA); printf("Input the second number(int):\n"); flag = scanf("%d", &inputB); while(flag == 0 || getchar() != '\n') { setbuf(stdin, NULL); while (getchar() != '\n'); printf("Input type error,please enter again: "); flag = scanf("%d", &inputB); } printf("inputB = %d.\n", inputB); getchar(); return 0; } |
运行示例如图:

二、C语言Windows平台:
在Windows平台下,将上面代码中的“setbuf(stdin, NULL); /* Linux系统中用以清空缓冲区的函数.*/”换为:
1 | fflush(stdin); |
也可以实现相同功能。
三、C++ Linux && Windows平台:
C++里面这种方法其实我一直在用,以前的几篇文章里就有:《C++模板类之堆排序》。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <iostream> int main() { using namespace std; cout <<"Input the first number(int):\n"; int inputA; /* 如果输入数据的类型不匹配,或者输入中含有非法字符,则清空缓存区并要求重输.*/ while(!(cin >>inputA) || cin.get() != '\n') { cout <<"Input type error,please enter again: "; /*下面两句搭在一起使用可以有效清空缓存区.*/ cin.clear(); while(cin.get()!='\n') continue; } cout <<"\tinputA = "<<inputA<<endl; while(!(cin="">>inputB) || cin.get() != '\n') { cout <<"Input type error,please enter again: "; cin.clear(); while(cin.get()!='\n') continue; } cout <<"\tinputB = "<<inputB<<endl; return 0; } |
运行示例如图:

四、C++ Windows平台:
在Windows平台,上面用以清空缓存区的两行可以替换为:
1 2 | cin.clear(); fflush(stdin); |
不过顺序不能变。
走过路过的朋友有什么更好的方法,希望不吝赐教。
声明:本文采用 BY-NC-SA 协议进行授权 | 星期九
原创文章转载请注明:转自《清空输入缓冲区&&处理错误输入的几种方法》
两个平台切来切去多麻烦啊
问下Harid,你这个Ajax的评论效果 是用的什么插件?WordPress Thread Comment吗?
@夜泊枫桥, 嗯,就是它。我用它实现评论嵌套、评论回复邮件通知、评论Ajax、前台回复、前台删除等。
nice,不过gcc下木有fflush(),得自己写个
@Hakz, 我有说哦,fflush()只能用在Windows平台。GCC下可以用setbuf().
讲的蛮详细的,对于那些新手来说还是蛮有用的。
不错 这个可以有 嘿嘿
@小托, 最近星期九用IE访问会有点不友好哦,我正在一点一点修改它。
@Harid, 我的都是IE内核。。
@小托, IE着实让我蛋疼呀,不兼容它吧,在中国用它的人太多了,银行呀、学校呀之类的的网站都是基于IE开发的,导致中国人无法脱离它。我慢慢搞定它吧。
@Harid, 那是必须的
让输入int,输入了字母,还是老实的转了吧?呵呵。
@Kada, 有一个国外的论坛上看到说这个问题,于是总结了一下。一个不错的论坛,可以围观一下:http://cboard.cprogramming.com/c-programming/67891-flush-input-buffer.html
@Kada, 链接给错了,是这个:http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1044873249&id=1043284392
代码高亮插件就是不爽。我现在都是用你给我推荐的fayaa.com/code/转成HTML再贴上来。
@Kada, 那个帖这种代码不太好,不可以缩进,帖一些短代码呀那个网站是非常不错。
@Harid, 你是说插件帮忙自动缩进吗?我都是自己控制好格式后再转换的。主要是如果代码太宽了,插件就产生一个滚动条,很烦。那个是给你换行了,还好点。
@Kada, 插件能自动缩进呀,只要粘贴代码的时候按格式在HTML模式下粘贴就能自动帮你缩进。
那个滚动条的确是插件自作多情了。
Random Posts
Recent Posts
Recent Comments
By Plastic injection mould
By OOZJ
By Jusbe
By 互联网战
By 互联网战
By ixwebhosting
Blogroll
Categories
Tag Cloud
360 5800 Alexa C++ Chrome Cisco Dedecms Discuz Fcitx Fedora GFW Gravatar IE Linux Mobile ModelSim Music QT Quartus Shell Verilog VPN VPS Windows Wordpress XAMPP Xilinx xp 下载 垃圾评论 情感 手机 插件 星期九 注册 电子信息 程序设计 站长工具 缩略图 网络应用 考研 胡思乱想 西工大 视频 软件Meta