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

📄 evaluate.cpp

📁 计算器程序
💻 CPP
字号:
//****************************************************************
//This software may not be distributed further without permission from
// Sun Xueshi's Group
//      
//This software is distributed WITHOUT ANY WARRANTY. No claims are made
// as to its functionality or purpose.
// 
//Authors: 孙学诗 ,孙海洋
// Date: 12/4/03
// 
//****************************************************************

#include "evaluate.h"
#include<cmath>

using namespace std;

//Evaluate--Constructor: give default value "0" to DivedeByZero 
Evaluate::Evaluate():DivideByZero(0) {}

//Run--Do evaluate expression
void Evaluate::Run() {
	DivideByZero = 0;
	char ch;
	fseek(stream, 0, SEEK_SET);       //Open stream file and get char from  beginning
	Optr.Push('#');                            //Make a sign: put # bottom of Stack
	GetInput();                                  //Get a value
	while ( Operator != '=' ||Optr.GetTop() !='#'){
		//get a operator
        	if (Operand >=0) 
        		Opnd.Push(Operand);
        	//if operator is ")" evaluate expression between '(' and ')'
                 if (Operator == ')'){
                          for(ch = Optr.Pop(); ch !='('; ch = Optr.Pop()) {
                      	       RightOpnd = Opnd.Pop();
                      	       LeftOpnd = Opnd.Pop();
                 	       Opnd.Push(DoOperator(LeftOpnd, ch, RightOpnd));
                          }
                          GetInput();
                 }
                 //evaluate expression according to the priority of operator
                 else {
                 	for(ch = Optr.Pop(); InStackPriority(ch)>InComingPriority(Operator); ch = Optr.Pop()){
                 		    RightOpnd = Opnd.Pop();
                 		    LeftOpnd = Opnd.Pop();
                 		    Opnd.Push(DoOperator(LeftOpnd, ch, RightOpnd));
                 	}
                 	Optr.Push(ch);
                 	if(Operator != '='){
                 	         Optr.Push(Operator);
                	         GetInput();
                 	}
                 }
        }	
	while(Optr.GetTop() !='#') {
		ch = Optr.Pop();
		RightOpnd = Opnd.Pop();
		LeftOpnd= Opnd.Pop();
		Opnd.Push(DoOperator(LeftOpnd, ch, RightOpnd));
	}
	//get result
	if(Opnd.IsEmpty()) 
		Result = Operand;
	else Result = Opnd.Pop();
	if(DivideByZero!=1)
		cout << Result <<endl<<endl;
}


//Interface--Get stream contain expression that is input
void Evaluate::Interface(FILE *tmp) {
	stream = tmp;
}	

//GetResult--Change result to proper form of string
string Evaluate::GetResult() {
	if(DivideByZero == 1)
		ResultText = "Zero can not be a divisor!";
	else {
		char ResultBuffer[50];
		sprintf(ResultBuffer, "%g", Result);   //change result to proper form into char array
		ResultText = ResultBuffer;
	}
	return ResultText;
}

//IsOperator--If character is operator, return ture, or false
bool Evaluate::IsOperator(char ch){
	if (strchr(Operators,ch))               // current character is contain in Operators array
		return true;
	else
		return false;
}

//GetInput--Get input from a stream
void Evaluate::GetInput() {
	char Buffer[30];
	char ch;
	int index = 0;
	ch = fgetc(stream);
        //get operands
        while ( !IsOperator(ch)){
       	        if (ch>='0'&&ch<='9'){
       		        Buffer[index] = ch;
       		        index++;
       	        }
       	        ch = fgetc(stream);
        }
        //get operators
        	Operator  = ch;

        if (index>0) {
       	        Buffer[index] = '\0';
       	        Operand = atoi(Buffer);
        }
        else
        	Operand = -1;
}

//InStackPriority--Get In Stack Priority
int Evaluate::InStackPriority(char ch){
	int isp;
	switch(ch){
		case'#': isp = -1;break;
		case'(' : isp = 1;break;
		case'*': 
		case'%':
		case'/': isp = 5;break;
		case'+':
	        case'-': isp = 3;break;
	        case')': isp = 8;break;
	        case'^': isp = 7;break;
	}
	return isp;
}

//InComingPriority--Get In Coming Priority
int Evaluate::InComingPriority(char ch){
	int icp;
	switch(ch){
		case'#': icp = -1;break;
		case'(' : icp = 8;break;
		case'*':
		case'%':	
		case'/': icp = 4;break;
		case'+':
	        case'-': icp = 2;break;
	        case')': icp = 1;break;
	        case'^': icp = 6;break;
	        case'=': icp = 0;break;
	}
	return icp;
}

//DoOperator--Evaluate with two operands and an operator
double Evaluate::DoOperator(double left,char op,double right){
       	    switch(op) {
       		    case '+' : return left + right;       //Do Addition
                     case '-' : return left - right;       //Do subtration
                     case '*' : return left * right;       //Do multiplication
                     case '/' : if (right == 0){             //If 0 is divisor, print error
                     	               cout<<endl;
                     	               cerr<<"Divide by 0!"<<endl;
                     	               DivideByZero = 1;       //sign 0 is divisor
                     	            }
                                    else return left / right;   //Do division
                     case '^' : return pow(left,right) ;   //Do power 
                     case'%': return left-right*int(left/right);   //Do" %" operator
       	    }
       	    return 0;
}

⌨️ 快捷键说明

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