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

简介:

代码:

#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再次读入) + 再次输入。


目录
相关文章
|
2天前
|
存储 编译器 C语言
c语言中char的作用类型
c语言中char的作用类型
38 0
|
2天前
|
存储 关系型数据库 MySQL
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
本篇文章来讨论MySQL字段的字符类型选择并深入实践char与varchar类型的区别以及在千万数据下的性能测试
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
|
2天前
|
C++
【C++】std::string 转换成非const类型 char* 的三种方法记录
【C++】std::string 转换成非const类型 char* 的三种方法记录
8 0
|
7月前
|
存储 SQL Oracle
对比下不同RDBMS数据库中对字符数据类型处理的差异 - 为什么我们要尽量避免使用CHAR数据类型?
对比下不同RDBMS数据库中对字符数据类型处理的差异 - 为什么我们要尽量避免使用CHAR数据类型?
|
2天前
|
存储 人工智能 编译器
learn_C_deep_5 (温故知新、sigend char a = -128的深度理解、unsigned int类型的写法规范)
learn_C_deep_5 (温故知新、sigend char a = -128的深度理解、unsigned int类型的写法规范)
|
2天前
|
存储 算法 安全
C++系列-第1章顺序结构-9-字符类型char
C++系列-第1章顺序结构-9-字符类型char
|
2天前
|
存储 自然语言处理 安全
【C++11保姆级教程】空指针(nullptr),long long类型,char16_t和char32_t类型
【C++11保姆级教程】空指针(nullptr),long long类型,char16_t和char32_t类型
【C++11保姆级教程】空指针(nullptr),long long类型,char16_t和char32_t类型
|
7月前
|
存储 数据库
SAP CDS view 如何将 CHAR 类型的数据字段和当前系统日期比较
SAP CDS view 如何将 CHAR 类型的数据字段和当前系统日期比较
63 0
|
8月前
|
存储 关系型数据库 MySQL
MySql 字符串类型 - char、varchar
MySql 字符串类型 - char、varchar
67 0
|
8月前
|
存储 C语言
C语言:char与unsigned char类型数据的范围
unsigned char 的范围是 0~255,当 i=255 时,i++变为0,从0到255无限循环,因此程序运行结果为死循环
154 0