⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exp19_1.cpp

📁 高等教育出版社出版的C++程序设计同步实验范例 希望对用这本教材得同学有点帮助
💻 CPP
字号:
/*为模拟简单计算器程序添加异常处理(参见教材【例7.7】)。包括被零除、整型数溢出和输入非法字符。
[提示]首先定义四种异常,尽管没有数据域,为通用还是定义为模板。被零除、整型数溢出两个异常在
Calculator::Compute()函数中抛出。将Calculator::Cal()中的读入开关语句定义为try块,输入非法字
符异常放开关语句中,栈空在栈模板中。四个catch子句排在try块外,子句中包括清栈命令。
*/
//测试用:6/0=;65535*65535=;4+6*3+k=;6+6+=;
#include<iostream.h>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include"Exp19_1.h"  //链栈模板定义文件

template<typename T>class divided_by_zero{
public:
	divided_by_zero(){}
	void print(){cerr<<"因被零除,发生算术溢出,跳过"<<endl;}
};

template<typename T>class intoverflow{
public:
	intoverflow(){}
	void print(){cerr<<"因整型数溢出,跳过"<<endl;}
};

template<typename T>class invalid_letter{
public:
	invalid_letter(){}
	void print(){cerr<<"因输入非法字母,跳过"<<endl;}
};

class Calculator{                                 //简易计算器类
	Stack<int> Nstack;
	Stack<char> Ostack;
public:
	Calculator(void){};
	void Cal(void);                               //计算器运算程序
	void GetTwoNum(int &Num1,int &Num2);
	void Compute(char Opr);
	void Clear(void);
};
void Calculator::Clear(){
	Nstack.MakeEmpty();
	Ostack.MakeEmpty();
}
void Calculator::GetTwoNum(int &Num1,int &Num2){
	Num1=Nstack.Pop();
	Num2=Nstack.Pop();
}
void Calculator::Compute(char Opr){
	int Num1,Num2;
	double a;
	if(Opr!='=') GetTwoNum(Num1,Num2);
	switch(Opr){
		case '+':a=double(Num2)+double(Num1);
			if(a<INT_MAX&&a>INT_MIN) Nstack.Push(Num2+Num1);//结果压栈
			else throw intoverflow<int>();
			break;  
		case '-':a=double(Num2)-double(Num1);
			if(a<INT_MAX&&a>INT_MIN) Nstack.Push(Num2-Num1);//结果压栈
			else throw intoverflow<int>();
			break;  
		case '*':a=double(Num2)*double(Num1);
			if(a<INT_MAX&&a>INT_MIN) Nstack.Push(Num2*Num1);//结果压栈
			else throw intoverflow<int>();
			break;  
		case '/':if(Num1!=0) Nstack.Push(Num2/Num1);
			else throw divided_by_zero<int>();
			break;
		case '=':cout<<Nstack.Pop()<<endl;           //输出结果
	}
}
void Calculator::Cal(){
	bool b1=true,b2=true;
	char ch1,ch2,str[50];
	int k=-1;
	while(b2){
		cin>>ch1;
		if(ch1>='0'&&ch1<='9'){
			k++;
			str[k]=ch1;                           //数字字符添入串中
		}
		else{
			if(k>=0){
				str[k+1]='\0';                       //数字串生成
				Nstack.Push(atoi(str));				//数字串转换为整数后压栈
				k=-1;
			}
			try{//try块的位置很重要,否则会出错
			switch(ch1){
			case 'c':
				Clear();
				break;
			case '+':
			case '-':
				while(!Ostack.IsEmpty()){
					ch2=Ostack.Pop();   //不会有比'+' '-'优先级低的
					Compute(ch2);
				}
				Ostack.Push(ch1);
				break;
			case '*':
			case '/':
				while(!Ostack.IsEmpty()&&b1){
					ch2=Ostack.Pop();            //把栈顶运算符弹出
					if(ch2=='*'||ch2=='/')        //比较优先级
						Compute(ch2);            //新的优先级并不高
					else{						  //新的优先级高
						Ostack.Push(ch2);         //先把原栈中的运算符压回去
						b1=false;
					}
				}
				Ostack.Push(ch1);             //再把新的运算符压栈
				b1=true;           //此句保证乘除从左倒右进行
				break;
			case '=':
				while(!Ostack.IsEmpty()){
					ch2=Ostack.Pop();
					Compute(ch2);
				}
				Compute(ch1);
				break;
			case 'z':
				b2=false;
				break;
			default:throw invalid_letter<int>();
			}
			}
			catch(divided_by_zero<int> &eObj){Clear();eObj.print();}
			catch(intoverflow<int> &eObj){Clear();eObj.print();}
			catch(invalid_letter<int> &eObj){Clear();eObj.print();}
			catch(stack_is_empty<int> &eObj){Clear();eObj.print();}
		}
	}
}
void main(){
	Calculator Calcul;
	Calcul.Cal();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -