完整的数学表达式求值计算器(标准C++语言编写)
程序代码:
#include <iostream> //标准输入输出流头文件。 #include <cstdlib> //标准“exit()”所包含的头文件。 #include <cmath> //标准数学库函数。 #include <iomanip> //标准流格式头文件。 #include <windows.h> //Windows头文件。 #include "stack.h" //自定义(栈)类模板头文件。 using namespace std; //命名空间。 stack<long double> A; //数据栈(存有效数字)。 stack<char> B; //字符栈(存运算符)。 void Run(); //综合运算函数。 int Priority( char ); //运算符优先级。 long double Computing( char ); //简单运算函数。 void SetColor( unsigned short FColor=4, unsigned short BColor=0 ) //字体颜色设置。 { HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute( hCon, FColor | BColor ); } void help() //帮助与程序说明。 { cout<<"&-Calculator 1.1---------------------------------------->\n" <<"数学表达式求值计算器: 程序编写者(C++ Language): 刘华军\n" <<"说 明:(^)是乘方运算符,键入(S)清屏,键入(Q)退出。\n" <<"本程序支持负数运算以及错误警告。\n" <<"请在下面输入数学表达式: 例 6+(6+8/2*(8-5)^8)*2\n" <<"&---------------------------------------------->"; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main() { system("cls"); //清屏函数。(调用DOS命令) help(); //帮助与程序说明。 for(;;) //无限循环。 Run(); //调用综合运算函数。 return 0; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Run() { int c,d; long double P,Z=0; const long double Max=999999999999.999; //long double 的最长数字是15位包括小数点后面的精度位数,小数点不包括在内。 char ch,ab=0; //"ab"变量用来标记上一次进栈的是数字还是运算符。 cout<<endl; SetColor(7,0); cin.clear(); cin.sync(); //清空输入流。 A.clear(); B.clear(); //清空A-B栈。 while ( cin ) //检查输入流是否可用。 { cin.get( ch ); //输入表达式。(能读取空格符、换行符、回车符。) switch ( ch ) { case '(': if ( ab !='A' ) //左括号前不能是数字。 { B.push( ch ); break; } SetColor(); cerr<<"Error:01"; return; case ')': if ( B.find('(') && ab =='A' ) //运算符栈中必须有左括号与右括号前必须是数字。(右括号不进栈) { while ( B.top() != '(' ) { try //异常定义。(可能抛出异常的语句) { A.push( Computing(B.top()) ); } //如果出现异常,函数内部会抛出异常。 catch ( long double ) //捕获并处理异常。 { SetColor(); cerr<<"Error:04"; return; } B.pop(); //运算符出栈。 } B.pop(); break; //左括号出栈。 } SetColor(); cerr<<"Error:01"; return; case '+': case '-': case '*': case '/': case '^': if ( ch =='-' && ab !='A' ) //当上一次进栈的数据是运算符,当前'-'为负数标号。 { cin.putback( ch ); //此函数将当前字符送回到缓冲区中。 if ( cin>>P ) //检查读取的数字是否有效。 { A.push( P ); ab='A'; break; } //读取的数字进栈,"ab"变量记录下来。 SetColor(); cerr<<"Error:01"; return; } else if ( ab =='A' ) //运算符前面必须是数字。 { while ( !B.empty() && B.top() != '(' ) //运算符栈为空或栈顶元素为左括号时停止循环。 { c= Priority( B.top() ); d= Priority( ch ); if ( c >= d ) { try //异常定义。(可能抛出异常的语句) { A.push( Computing(B.top()) ); } //如果出现异常,函数内部会抛出异常。 catch ( long double ) //捕获并处理异常。 { SetColor(); cerr<<"Error:04"; return; } B.pop(); } else break; //跳出循环。 } B.push( ch ); ab='B'; break; //运算符进栈,"ab"变量记录下来。 } SetColor(); cerr<<"Error:01"; return; case '\n': case '\r': case '=': if ( B.empty() && A.empty() || B.find('(') || ab !='A' ) //A-B栈不能为空,等号前不能出现左括号和不能没有数字。 { SetColor(); cerr<<"Error:01"; return; } else if ( B.empty() && !A.empty() ) //等号前只有一个数字。 Z= A.top(); while ( !B.empty() ) { try //异常定义。(可能抛出异常的语句) { Z= Computing( B.top() ); } //如果出现异常,函数内部会抛出异常。 catch ( long double ) //捕获并处理异常。 { SetColor(); cerr<<"Error:04"; return; } A.push( Z ); B.pop(); } A.pop(); //清空最后一个数据栈。 if ( Max < Z ) //检查结果是否超出最大数据范围。 { SetColor(); cerr<<"Error:03"; return; } SetColor(2,0); cout<<fixed<<setprecision(3)<<Z; return; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': cin.putback( ch ); //此函数将当前字符送回到缓冲区中。 if ( cin>>P && ab !='A' ) //检查读取的数字是否有效,上一次进栈的数据不可以还是数字。 { A.push( P ); ab='A'; break; } //读取的数字进栈,"ab"变量记录下来。 SetColor(); cerr<<"Error:01"; return; case 'Q': case 'q': exit(1); //退出程序。 case 's': case 'S': system("cls"); help(); return; //清屏后打印帮助与程序说明。 default : SetColor(); cerr<<"Error:02"; return; } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int Priority( char x ) { switch ( x ) { case '+': case '-': return 0; //将运算符优先级标记为数字。 case '*': case '/': return 1; //将运算符优先级标记为数字。 case '^': return 2; //将运算符优先级标记为数字。 default : exit(1); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// long double Computing( char x ) { int n; long double a,b; switch ( x ) { case '+': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。 a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。 return a+b; case '-': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。 a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。 return a-b; case '*': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。 a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。 return a*b; case '/': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。 a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。 if ( b != 0 ) return a/b; throw b; //抛出异常。 case '^': n= static_cast<int>( A.top() ); A.pop(); //(数字栈)栈顶元素(强制转换成整型)赋给n,然后出栈。 a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。 return pow(a,n); //数学库函数。(乘方运算函数) default : exit(1); } }[local]1[/local]