(八十八)对非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再次读入) + 再次输入。

时间: 2024-08-30 11:37:53

(八十八)对非char类型在cin时输入字符的相关文章

DockOne微信分享( 八十八):PPTV聚力传媒的Docker与DevOps

本文讲的是DockOne微信分享( 八十八):PPTV聚力传媒的Docker与DevOps[编者的话]DevOps是2009年前后提出的一个概念,提倡开发(Development)和运维(Operations)这两个领域的高度协同.从而在完成高频率部署的同时,提高生产环境的可靠性.稳定性.弹性和安全性.本次分享介绍了PPTV聚力传媒以Docker技术为支撑,在DevOps方面做的优化,包括: DevOps简介 Docker在PPTV的应用 DevOps与Docker的结合 实现方案 DevOps

c++-为何char【17】无法输入字符

问题描述 为何char[17]无法输入字符 #include #include using namespace std; class Date{ public: Date(int y, int m, int d); ~Date(){} Date(){} int getyear()const{ return year; } int getmonth()const{ return month; } int getday()const{ return day; } Date(Date &birthda

struts2上传下载,下载非txt类型文档后台报错,但文件成功下载了

问题描述 struts2上传下载,下载非txt类型文档后台报错,但文件成功下载了 下载非txt类型文档时后台报了个异常:(下载txt不报异常) java.lang.IllegalStateException: Cannot call sendError() after the response has been committed at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:451)

Java核心技术卷I基础知识3.3.3 char类型

3.3.3 char类型 char类型原本用于表示单个字符.不过,现在情况已经有所变化.如今,有些Unicode字符可以用一个char值描述,另外一些Unicode字符则需要两个char值.有关的详细信息请阅读下一节. char类型的字面量值要用单引号括起来.例如:'A'是编码值为65所对应的字符常量.它与"A"不同,"A"是包含一个字符A的字符串.char类型的值可以表示为十六进制值,其范围从\u0000到\Uffff.例如:\u2122表示注册符号(TM),\u

二十八条改善 ASP 性能和外观的技巧 1-6(From Ms China)——七月份的文章,好像还没人转过

技巧|性能 二十八条改善 ASP 性能和外观的技巧 Len Cardinal,高级顾问,Microsoft Consulting Services George V. Reilly Microsoft IIS Performance Lead 改编自Nancy Cluts 的文章 开发人员技术工程师 Microsoft Corporation 2000 年 4 月 摘要:本文介绍优化 ASP 应用程序和 VBScript 的技巧. 引言 性能是一个特征.您必须预先设计性能,否则您以后就得重写应用

二十八条改善 ASP 性能和外观的技巧(1-7)

技巧|性能 二十八条改善 ASP 性能和外观的技巧 Len Cardinal,高级顾问,Microsoft Consulting Services George V. Reilly Microsoft IIS Performance Lead 改编自Nancy Cluts 的文章 开发人员技术工程师Microsoft Corporation 2000 年 4 月 摘要:本文介绍优化 ASP 应用程序和 VBScript 的技巧. 目录 技巧 1:将经常使用的数据缓存在 Web 服务器上 技巧 2

C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(十八)

C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(十八) 完美精灵之八面玲珑(WPF Only)② 紧接着上一节,首先得解释一下为什么需要将这272张图片合成为一张大图.因为如果游戏中还有装备.坐骑等其他设置,那么我们就需要对图片源进行时时的合成:同时对272张甚至更多的图片进行合成效率高还是对2张大图进行合成效率高这是显而易见的.在本节例子中,主角由身体(衣服)及武器两个部分组成:因此,我们还需要定义一个交错数组来保存已经加载的角色装备合成图到内存中: //

(八十)第五章编程练习

1.编写一个要求用户输入两个整数的程序.该程序将计算并输出这两个整数之间(包括这两个整数)的所有整数的和.这里假设先输入较小的整数.例如,如果用户输入的是2和9,则程序指出2-9之间的所有整数和为44.(增加难度,由程序自行判断哪个大哪个小)   答: #include<iostream> int main() { using namespace std; int a, b; cout << "请输入两个数字,系统将自动帮你计算这两个数字之间(包括这两个数字)所有整数的和

JAVA之旅(十八)——基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用

JAVA之旅(十八)--基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用 JAVA把完事万物都定义为对象,而我们想使用数据类型也是可以引用的 一.基本数据类型的对象包装类 左为基本数据类型,又为引用数据类型 byte Byte int Integer long Long boolean Booleab float Float double Double char Character 我们拿Integer来举例子 //整