文章1:http://bbs.csdn.net/topics/390471195
文章2:http://bbs.csdn.net/topics/300129123
文章3:http://blog.csdn.net/tw_345/article/details/49816231
getchar(),scanf().输入后如何立即清除缓冲区。
我在做一个菜单选项,一次只要求接受一个字符,可是用getchar()输入时,后面的回车被当作
第二次输入,还有如果一次输入很多字符,后面的字符也会带到下次循环。
请问在getchar()之后如何能立刻清除缓冲区。
我的环境时redhat linux 9.0.
方法1:
1 2 3 4 |
ch = getchar(); getchar(); 两次getchar();即可 或者fflush(stdin); |
方法2:while(getchar()!=’\n’);★C51推荐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
每次getchar()之后 while(getchar()!='\n'); /* 而且这个移植性比较好*/ 例如: #include <stdio.h> int main() { char ch1,ch2; scanf("%c",&ch1); while ((ch2 = getchar())== '\n'); //在Fedora 10上测试了一下,使用fflush(stdin)不起作用;使用循环来判断就行了 printf("ch1 :%c\n",ch1); printf("ch2 :%c\n",ch2); return 0; } |
方法3:
1 |
//scanf(" %c", &ch); //方法3:(前边添加一个空格)消除上一个'/n' 有效 |
用↓这个实现比较好点
while(getchar()!=’\n’);
fflush这个并不是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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#include<stdio.h> int main(){ float price_1=1.25,price_2=0.65,price_3=0.89; float quantity_1=0.0,quantity_2=0.0,quantity_3=0.0; float total_price=0.0,total_quantity=0.0; float total_price_end=0.0,preferential_price=0.0,freight=0.0,Price=0.0; char ch; while (ch!='q') { printf("欢迎来到文哲商店!~在下面选择你喜爱的商品,按q确认\n"); printf("a)朝鲜鱼 1.25美元/磅\nb)甜菜 0.65美元/磅\nc)胡萝卜 0.89美元/磅\n"); scanf("%c",&ch); switch (ch) { case 'a': printf("你的最终数量为:%f\n请输入朝鲜鱼的数量:",quantity_1); scanf("%f",&quantity_1); getchar(); break; case 'b': printf("你的最终数量为:%f\n请输入甜菜的数量:",quantity_2); scanf("%f",&quantity_2); getchar(); break; case 'c': printf("你的最终数量为:%f\n请输入胡萝卜的数量:",quantity_3); scanf("%f",&quantity_3); getchar(); break; default: break; } } printf("你选择%f磅朝鲜鱼,共%f美元\n",quantity_1,quantity_1*price_1); printf("你选择%f磅甜菜,共%f美元\n",quantity_2,quantity_2*price_2); printf("你选择%f磅胡萝卜,共%f美元\n",quantity_3,quantity_3*price_3); total_price=price_1*quantity_1+price_2*quantity_2+price_3*quantity_3; total_quantity=quantity_1+quantity_2+quantity_3; if (total_price>=100) { printf("*你的总价为:%f,超过了100美元,可享受95折优惠\n",total_price); total_price_end=total_price*0.95; preferential_price=total_price-total_price_end; }else{ printf("*你的总价为:%f,没有超过100美元,无优惠\n",total_price); total_price_end=total_price; preferential_price=0.0; } printf("*你的优惠价格为:%f\n",preferential_price); printf("下面开始计算运费\n*你的总磅数是:%f\n",total_quantity); if (total_quantity<=5) { freight=3.5; }else if(total_quantity<20){ freight=10; }else{ freight=8+total_quantity*0.1; } printf("*你的运输费用为:%f\n",freight); Price=total_price_end+freight; printf("**********\n你的总费用为%f\n",Price); return 0; } |
模拟购物商店,但是却发生了意想不到的事:
在前面的while语句中,出现了循环两次的情况。
仔细检查代码,并没有语法错误。
于是,我就回到寝室和小强(大牛)请教。
他也好久没碰c了,首先值得肯定的是,语法是没有问题。我们打了注释,发现和switch,printf,getchar,while这些都没关系,可以肯定的是问题还是出自scanf,我们将问题归结为可能是操作系统或是C语言的底层
我用的mac系统,是在Xcode上码的,我把代码发到他的VS上,期待的看着打印结果,~~却发现也有同样的问题。
于是我们加了C++的头文件,稍稍修改,发现果然C++并没有这个问题!
为了找出这个底层的原因,我们开始断点,发现,输入11之后,再次循环while时,scanf没有提示输入直接跳过,而此时ch由‘a’变成了‘\n’。正是因为这个‘\n’,使主菜单打印了两次
上网搜索这个换行符究竟什么来头,查到了“缓冲区”这个概念
并说及时刷新缓冲区可以解决这个问题
一种跨平台的方法 getchar()
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#include<stdio.h> int main() { float price_1=1.25,price_2=0.65,price_3=0.89; float quantity_1=0.0,quantity_2=0.0,quantity_3=0.0; float total_price=0.0,total_quantity=0.0; float total_price_end=0.0,preferential_price=0.0,freight=0.0,Price=0.0; char ch; while (ch!='q') { printf("欢迎来到文哲商店!~在下面选择你喜爱的商品,按q确认\n"); printf("a)朝鲜鱼 1.25美元/磅\nb)甜菜 0.65美元/磅\nc)胡萝卜 0.89美元/磅\n"); scanf("%c",&ch); switch (ch) { case 'a': printf("你的最终数量为:%f\n请输入朝鲜鱼的数量:",quantity_1); scanf("%f",&quantity_1); break; case 'b': printf("你的最终数量为:%f\n请输入甜菜的数量:",quantity_2); scanf("%f",&quantity_2); break; case 'c': printf("你的最终数量为:%f\n请输入胡萝卜的数量:",quantity_3); scanf("%f",&quantity_3); break; default: break; } getchar(); //fflush(stdin);//刷新缓冲区 } printf("你选择%f磅朝鲜鱼,共%f美元\n",quantity_1,quantity_1*price_1); printf("你选择%f磅甜菜,共%f美元\n",quantity_2,quantity_2*price_2); printf("你选择%f磅胡萝卜,共%f美元\n",quantity_3,quantity_3*price_3); total_price=price_1*quantity_1+price_2*quantity_2+price_3*quantity_3; total_quantity=quantity_1+quantity_2+quantity_3; if (total_price>=100) { printf("*你的总价为:%f,超过了100美元,可享受95折优惠\n",total_price); total_price_end=total_price*0.95; preferential_price=total_price-total_price_end; }else{ printf("*你的总价为:%f,没有超过100美元,无优惠\n",total_price); total_price_end=total_price; preferential_price=0.0; } printf("*你的优惠价格为:%f\n",preferential_price); printf("下面开始计算运费\n*你的总磅数是:%f\n",total_quantity); if (total_quantity<=5) { freight=3.5; }else if(total_quantity<20){ freight=10; }else{ freight=8+total_quantity*0.1; } printf("*你的运输费用为:%f\n",freight); Price=total_price_end+freight; printf("**********\n你的总费用为%f\n",Price); return 0; } |
如上,解决了那个的问题。
第二天,我想既然是c才会有的问题,我便翻开那本老朋友《C Primer Plus》
果然有谈到“缓冲区”!
上面谈到的知识点大致如下:
缓冲分为两类:完全缓冲和行缓冲。
对完全缓冲输入来说,缓冲区满时被清空。这总类型的缓冲通常出现在文件输入中。缓冲区的大小取决于系统,但512字节和4096字节是常见的值。
对行缓冲输入来说,遇到一个换行字符时被清空缓冲区。键盘输入是标准的行缓冲,因此按下回车键将清空缓冲区。
文件结尾(EOF)换行符(\n)
针对这个问题,书上的解决方案是
1 2 3 |
while(getchar()!='\n'){ continue; } |
转载请注明:徐自远的乱七八糟小站 » 清除字符输入后面的回车, getchar(),scanf().输入时缓冲区中都会多一个回车。如何清楚缓冲区。