C++--输入cin输出cout小结

代码1: 

//向用户提出一个"Y/N"问题 然后把用户输入的值赋给answer变量
//要求 针对用户输入"Y/y"或"N/n"进行过滤
//罚决程序可能存在的任何问题 想想为什么
#include<iostream>

int main(){
	char answer;
	std::cout<<"请问可以格式化您的硬盘吗?[Y/N]"<<"\n";
	std::cin>>answer;
	switch(answer){
		case 'y':
		case 'Y':
			std::cout<<"随便格式化硬盘是不好的"<<"\n"; 
			break;
		case 'N':
		case 'n':
			std::cout<<"您的选择是正确的!"<<"\n";
			break;
		default:
			std::cout<<"您的输入不符合要求!"<<"\n";
			break;
	} 
	std::cin.ignore(100,'\n');//够100个字符 或者接收到回车 就结束忽略 
	
	
	std::cout<<"输入任何字符结束程序!"<<"\n";  //暂停程序 
	std::cin.get();
	return 0;
} 

分析: 

std::cin.ignore(100,'\n');//够100个字符 或者接收到回车 就结束忽略 
std::cout<<"输入任何字符结束程序!"<<"\n";  //暂停程序 
std::cin.get();            

 如果没有cin的ignore函数的话 后两行其实在你没有另外输入字符的时候就已经结束程序了 因为在输入完answer之后按下的enter键留在了缓冲区没有被读取 所以std::cin.get(); 实际上接收了缓冲区的回车 从而没有允许你另外输入字符 解决办法就是 调用cin类里的ignore函数 忽略缓冲区的enter 从而达到想要实现的效果

代码2:

//编写一个温度单位转换程序 提示用户以[xx.x C]或[xx.x F]的格式输入
//要求:转换成相应摄氏或者华氏温度输出
#include<iostream>

int main(){
	//华氏温度 = 摄氏温度*9.0/5.0+32      9.0/5.0和32在C语言里可以用define宏定义 但是在这里学习用静态变量 
	const unsigned short ADD_SUBTRACT = 32;
	const double RATIO = 9.0/5.0;//关于const静态变量和define宏定义 各有何好处 
	
	double templeIn,templeOut;//输入的数值 
	char typeIn,typeOut;//输入的单位类型 
	
	std::cout<<"请以【xx.x C】或【xx.x F】的格式输入一个温度:";
	std::cin>>templeIn>>typeIn;
	std::cin.ignore(10,'\n');//忽略缓冲区内的回车 
	 
	switch(typeIn){
		case 'c':
		case 'C':
			templeOut = templeIn*RATIO+ADD_SUBTRACT;
			typeOut = 'F';
			typeIn = 'C';
			break;
		case 'f':
		case 'F':
			templeOut = (templeIn-ADD_SUBTRACT)/RATIO;
			typeIn = 'F';
			typeOut = 'C';
			break;
		default: typeOut = 'E';//错误信息 
	}
	if(typeOut!='E') std::cout<<templeIn<<typeIn<<"="<<templeOut<<typeOut<<"\n\n";//输入格式正确
	else std::cout<<"输入格式有误!"<<'\n';
	
	std::cout<<"请输入任何字符结束程序!\n";
	std::cin.ignore(100,'\n');//忽略掉缓冲区的回车
	return 0;
} 

从这个代码里有关输入格式xx.xF或者xx.xC里可以学到一些关于cin的东西,另外就是 宏定义和静态变量的优劣,二者的用法其实大体上来说是相通的但依然各有好处。除此之外就是用cin的ignore函数处理缓冲区无用数据。

对输入数据进行合法性检查

非法数据可能会导致程序甚至是整个系统崩溃,或者程序会变的毫无意义。

对输入的数据进行合法性检查的具体做法取决于具体的变量类型和他们的取值范围。比如说,C语言数组的越界问题,缓冲区溢出问题,这些都可能造成很大的漏洞,所以在现在讨论数据的合法,进行异常处理是十分有必要的。

在以上两个程序时我们用了switch来判断用户是否输入了程序预期的值,是很好的。但是还有一些潜伏的问题我们没有发掘出来,例如cin调用失败(无法将一个值赋给一个变量)时,程序依然会像cin调用成功一样自欺欺人。比如说如果在上面的第二个代码里将templeIn和templeOut的类型改为单精度的float,然后在输入的时候输入一个很扯的一大串数字,结果一定会出错,所以解决这些问题的方法之一就是对cin调用的结果不要做任何假设!

此案对象有几个专门用来报告其工作情况的成员函数,他们将返回一个真假值来表明cin的状态

-eof():如果到达文件(或输入)的末尾,返回true

-fail():如果cin无法工作,返回true

-bad():如果cin因为比较严重的问题(例如内存不足)而无法工作,返回true

-good():如果以上情况都没发生,返回true

#define和const

一:二者的机制

  • define是在预编译的时候展开替换的,const是编译运行阶段使用。
  • define没有类型,不做类型检查处理。只是替换。const常量有具体的类型,在编译的时候会进行类型检查。
  • define宏定义仅仅是替换宏定义不分配内存,变量定义分配内存,const会在内存中分配。

二:内存管理

define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存

const更节省空间,避免不必要的内存分配。选择const比define更省空间

思考:

对上面第二个代码的合法性检查有什么需要补充的,例如如果在输入时我输入了超过100个回车会怎么样,是不是就无法完全忽略掉了,那哟应该如何处理

猜你喜欢

转载自blog.csdn.net/J_SUNV/article/details/84872043
今日推荐