您的位置:首页 > 其它

(八十八)对非char类型在cin时输入字符

2015-12-14 19:46 169 查看
代码:

#include<iostream>
const int max = 5;
int main()
{
using namespace std;
double fish[max];
cout << "Please enter the weights of your fish.\n";
cout << "You may enter up to " << max << " fish <q to terminte>.\n";
cout << "fish #1: ";
int i = 0;
while (i < max&&cin >> fish[i])	//i初始为0,所以小于max(5),然后cin>>fish[i]指给数组i输入数值,假如这2个都是真,于是执行下面的循环
//假如i为5或者更大,或者无法输入进入数组fish,即fish[i]不会被赋值,那么就不会执行这个循环
{
if (++i < max)cout << "fish #" << i + 1 << ": ";	//++i<max是i+1后看是否比max小,这个时候已经加完了,后面i+1就是++i后的i+1
//假如初始i为0,那么++i为1,i+1为2.上面有fish #1.于是正常显示fish #2;但fish #2实际是fish[1](因为fish[0]才是第一个成员)
//虽然是if,但是在判断语句已经++i了,所以i实际上已经+1了。
//当i=3时,++i<5,于是后面输出的是fish #5(4+1=5)当i=4时,++i<5不成立(因为++i是5),跳过if,但是在while的语句里,i并不<5,于是结束while循环
}

//以上利用while判断语句中的cin>>fish[i]进行输入,遇见非法输入则停止while(因为表达式为false)。
//然后利用if中的++i对i进行增量,
//从而达到若能输入,且判断符合要求,则将相应的数据输入数组之中。

double total = 0.0;	//初始化total=0,double类型
for (int j = 0;j < i;j++)	//j初始为0
total += fish[j];	//实际为total=total+fish[j],因为j随着for循环更新而加1,从而加到fish[4]

if (0 == i)
cout << "No fish\n";	//当i=0时,原因在于上面cin>>fish[0]输入失败,所以没输入鱼,所以显示no fish
else
cout << total / i << " = average weight of " << i << " fish.\n";	//假如i=2,那么++i之前是1,也就是fish[0]和fish[1]输入成功,共2个成员。以后同。

char m;
cin>>m;
cout << m << endl;

cout << "Done.\n";
system("pause");
return 0;
}


说明:

①fish是double类型数组。

当cin>>fish[i]时,即给double类型数组中一个成员赋值时,假如输入的是数字,则赋值成功;假如输入的是字母,则该表达式返回false。

于是在while的判断语句里,返回false,于是跳过循环部分,执行下一段语句。

这说明:读取失败的表达式,返回值是false

②当cin>>fish[i]失败后,fish[i]并没有被赋值。

在后面,char m;其后的两行代码,都没有被执行。

原因在于,当cin应该读取一个int类型失败之后,其返回一个false值,并且被标记一个错误标记(不清楚其作用原理,但实际测试是之后所有cin将不被执行)

这说明:读取失败,之后的cin都无法执行。

③假如在cin>>m;之前,加入一行代码cin.clear();

那么在执行代码的时候,假如先输入a,那么cin>>m;直接读取了'a'这个字符,于是在cout<<m<<endl;这行代码输出了a。

这说明:读取失败的字符,被留在了输入缓存区之中。

④假如先输入一个正确的double类型数字,再输入一个不符合要求的字符,返回的结果是并没有影响数组fish。

这说明:输入不符合要求的字符,不影响变量的值。

特别注意:

&& 的执行逻辑为:先判断左边,假如为真,再执行右边。假如返回值为false,那么直接跳过右边不再执行。

例如while (i < max&&cin >> fish[i])这句,因为当i为5时,i<max为false,停止判断&&右边的值;

假如不是这样的话,那么虽然i不小于max,但是依然要执行判断cni>>fish[i],那么结果就是要再次输入,然后根据输入判断输入返回值是true还是false。

清空输入缓存区:

假如我们需要程序在读取到不符合要求的字符时,做出提示,并清除输入缓存区,可以这么做:

代码:

#include<iostream>

int main()
{
using namespace std;
int a;
cout << "输入一个数字:";
cin >> a;
while (!cin)
{
cout << "请输入数字,不要输入不符合要求的内容" << endl;
cout << "请在这里重新输入:";
cin.clear();	//清除掉输入错误的标记
cin.sync();	//清空缓存区,防止下一行cin代码再次读取到,从而陷入死循环
cin >> a;
}
cout << "你输入的数字为:" << a << endl;
system("pause");
return 0;
}


输出:

输入一个数字:f
请输入数字,不要输入不符合要求的内容
请在这里重新输入:ffff
请输入数字,不要输入不符合要求的内容
请在这里重新输入:3
你输入的数字为:3
请按任意键继续. . .


说明:

①在这里,使用了2行代码,第一行代码cin.clear()用来清除错误标记,但是由于之前输入的字母依然在缓存区之内,将被cin>>a再次读取,于是会陷入无限的死循环中。

②在while语句里,使用!cin,假如cin无法输入,则返回的是false,而!cin返回的则是true(因为!是true和false转换),于是执行循环

于是,假如无法输入,则执行while里面的循环语句——提示 + 清除错误标志 + 清除输入缓存(防止cin再次读入) + 再次输入。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: