测试环境:win10+vs2013
本计算器支持:带括号的浮点型四则运算,忽略输入的空格和换行符,遇到特殊字符抛出异常信息,代码量少但功能齐全
1、实现了四则运算的优先级,括号->乘除->加减
2、有非法输入检查和提示,区分英文和特殊字符
3、括号成对性检查,有左括号必须对应有右括号
4、第一个字符不允许是等号、分号、右括号
程序如下:
1 /* 2 *creator:wffos 20170323 3 */ 4 #include<iostream> 5 #include<string> 6 using namespace std; 7 enum EnumSymbol//符号集 8 { 9 END, NUMBER, PLUS = '+', SUB = '-', MULT = '*', DIV = '/', SEMICOLON = ';', EQUAL = '=', POINT = '.', LP = '(', RP = ')' 10 }; 11 12 double myNumber; 13 EnumSymbol myEnumSymble; 14 double plusSub(bool flag); 15 //异常 16 void errMsg(string s) 17 { 18 cout << s << endl; 19 throw (s); 20 } 21 //记录输入和输入类型 22 EnumSymbol getSymb() 23 { 24 char ch = 0; 25 cin >> ch; 26 switch (ch) 27 { 28 case 0: 29 return myEnumSymble = END; 30 case '+':case '-':case '*':case'/':case';':case '=':case'(':case')': 31 return myEnumSymble = EnumSymbol(ch); 32 case '0':case'1':case '2':case'3':case '4':case'5':case '6':case'7':case '8':case'9':case '.': 33 cin.putback(ch); 34 cin >> myNumber; 35 return myEnumSymble = NUMBER; 36 default: 37 if (isalpha(ch)) //如果是英文字母 38 { 39 //myEnumSymble = WORD; 40 errMsg(" err:illegal input.\n your inputs include word "); 41 } 42 //myEnumSymble = SYMBOL; 43 errMsg(" err:illegal input.\n your inputs include symble "); 44 } 45 } 46 //处理 47 double speProc(bool flag) 48 { 49 if (flag) 50 getSymb(); 51 switch (myEnumSymble) 52 { 53 case NUMBER://数字:返回数字,让getSymb()处理下一个输入 54 { 55 double n = myNumber; 56 getSymb(); 57 return n; 58 } 59 case LP://左括号:返回左括号后面的计算结果,注意要有右括号 60 { 61 double in = plusSub(true); 62 if (myEnumSymble != ')') 63 { 64 errMsg(" err:')' is expected:only '(' "); 65 } 66 getSymb(); 67 return in; 68 } 69 default: 70 return myEnumSymble; 71 } 72 } 73 //乘除 74 double multDiv(bool flag) 75 { 76 double left = speProc(flag); 77 while (1) 78 switch (myEnumSymble) 79 { 80 case MULT: 81 left *= speProc(true); 82 break; 83 case DIV: 84 { 85 double tmp = speProc(true); 86 if (tmp == 0) 87 errMsg (" divide by 0 "); 88 left /= tmp; 89 break; 90 } 91 default: 92 return left; 93 } 94 } 95 //加减 96 double plusSub(bool flag) 97 { 98 double left = multDiv(flag); 99 while (1) 100 switch (myEnumSymble) 101 { 102 case PLUS: 103 left += multDiv(true);//调用multDiv 104 break; 105 case SUB: 106 left -= multDiv(true);//调用multDiv 107 break; 108 default: 109 return left; 110 } 111 } 112 113 int main() 114 { 115 while (cin) 116 { 117 try 118 { 119 getSymb();//获取第一个输入 120 switch (myEnumSymble)//第一个输入特殊处理 121 { 122 case EQUAL: 123 errMsg(" err:begin with '=' "); 124 case SEMICOLON: 125 errMsg(" err:begin with ';' "); 126 case RP: 127 errMsg(" err:begin with ')' "); 128 default: 129 break; 130 } 131 cout << plusSub(false) << endl; 132 } 133 catch (string s) 134 { 135 cout << "\n input error ocured,try again: " << endl; 136 continue; 137 } 138 if (myEnumSymble == END) 139 break; 140 } 141 return 0; 142 }