支持:输入 + - * / % ^(右结合) 带小数的数字 无视空格 判断错误输入的能力 #include <stdio.h> #include <string.h> #include <stack> #include <ctype.h> #include <math.h> using namespace std; char *p; stack<char> op; stack<double> num; char getch()//获得下一个非空格字符 { while(*p==' ') p++; return *(p++); } double getnum(double num=0) { char temp; double d=10; while(temp=getch(),isdigit(temp)) { num=num*10+temp-48; } if (temp=='.') { while(temp=getch(),isdigit(temp)) { num=num+(temp-48)/d; d*=10; } } p--; return num; } double com(double a,double b,char op) { double sum; if (op=='%') sum=(int)a%(int)b; else { switch(op) { case '+':sum=a+b;break; case '-':sum=a-b;break; case '*':sum=a*b;break; case '/':sum=a/b;break; case '^':sum=pow(a,b);break; } } return sum; } void calcu() { double a,b,sum; char oper; a=num.top(); num.pop(); b=num.top(); num.pop(); oper=op.top(); op.pop(); sum=com(b,a,oper);//先出栈的是后面那个数 num.push(sum); } int prio(char op) { int priority; switch(op) { case ')':priority=1;break; case '+': case '-':priority=2;break; case '*': case '/': case '%':priority=3;break; case '^':priority=4;break; case '(':priority=5;break; default: priority=-1;break; } return priority; } int right(char op)//判断右结合的符号 { if (op=='^') return 1; return 0; } int legal(char *p) { while(*p) { if (isdigit(*p) || *p==' ' || prio(*p)!=-1); else return 0; p++; } return 1; } int main () { //freopen("1237.txt","r",stdin); char s[200],ch; double a; bool flag,err;//判断读入数据是否合法(flag判断数字和运算符是否交替出现 不包括括号) int bracket;//判断括号匹配 while(memset(s,0,sizeof(s)),gets(s),strcmp(s,"0")) { puts(s); p=s; bracket=0; if (!legal(p)) { printf("输入有非法字符/n/n"); continue; } flag=1; err=0; while(*p) { ch=getch(); if (ch!='(' && ch!=')')//判断输入是否合法 { if (flag!=(bool)isdigit(ch)) { printf("1输入不合法/n/n"); err=1; break; } else flag^=1; } if (isdigit(ch))//数字直接进栈 { a=getnum(ch-48); num.push(a); } else if ( ch==')' )//遇到后括号算到前括号为止 { if (flag) { printf("输入不合法 后括号前面应该是数字/n/n"); err=1; break; } if(!bracket) { printf("括号不匹配/n/n"); err=1; break; } else bracket--; while( op.top()!='(' ) calcu(); op.pop();//pop前括号 } else//计算ch前面比ch优先级大于等于的 前括号优先级高 但是不能计算 只能和后括号一起pop { if (ch=='(') { if (!flag) { printf("输入不合法 前括号前面应该是运算符/n/n"); err=1; break; } bracket++; } while(op.size() && op.top()!='(' && prio(op.top()) >= prio(ch) && !(right(ch) && ch==op.top())) { //栈不为空 不是前括号 优先级高于ch 处理右结合符号 calcu(); } op.push(ch); //右结合的符号 计算时前面那个符号不能是一样的 } } if (!err && flag)//最后一个肯定是数字 { err=1; printf("2输入不合法/n/n"); } if (err) { while(!op.empty()) op.pop(); while(!num.empty()) num.pop(); continue; } while(op.size()) calcu(); printf("%.2lf/n/n",num.top()); } }