#include
#include
#include
#include
char s[1000];
char *p;
void show_error_2(char* msg, char* exp_start, char* error_point)
{
char *q;
printf("\nError: ");
puts(msg);
puts(exp_start);
q = exp_start;
while(q < error_point)
{
putchar(' ');
q++;
}
printf("^\n");
throw 1;
}
void show_error(char* msg, char* error_point)
{
show_error_2(msg,p,error_point);
}
typedef struct
{
double array[100];
int top;
}stack;
inline int isNumeric(char s) // 判断是不是数字
{
return (s>='0'&&s<='9' || s=='.')?1:0;
}
int empty(stack* s) // 判断stack是不是为空
{
return s->top == 0;
}
void init(stack *s) // 初始化 stack
{
s->top = 0;
}
void push(stack* s, double a) // 入stack
{
s->array[s->top++] = a;
}
double pop(stack* s) // 出stack
{
if(!empty(s))
return s->array[--s->top];
}
double eval(char* s, char* e) // 解析算式
{
stack t;
double temp,temp2;
int cantakeadd;
int cantakemul;
int needop;
int needoperand;
char *p, *q, *r;
int flag;
char op = '+';
init(&t);
push(&t,0);
while(s
show_error("null expression",s);
p = s;
q = e;
cantakeadd = 1;
cantakemul = 0;
needop = 0;
needoperand = 0;
for(;p {
if(*p == ' ') continue; // 无视空格
else if(*p=='+' || *p == '-')
{
if(!cantakeadd)
show_error("cannot take additional operator!",p);
op = *p; // 更换操作符
cantakeadd = 0;
cantakemul = 0;
needop = 0;
needoperand = 1;
continue;
}
else if(*p == '*' || *p == '/')
{
if(!cantakemul)
show_error("cannot take additional operator!",p);
op = *p; // 更换操作符
cantakeadd = 0;
cantakemul = 0;
needop = 0;
needoperand = 1;
continue;
}
else
{
if(*p == '(') // 遇到左括号
{
r = p+1;
flag = 1;
while(flag)
{
p++;
if(p>=e)
show_error("( and ) not matched.",p);
if(*p=='(')
flag++;
if(*p==')') // 找到匹配的右括号
flag--;
}
temp = eval(r,p); // 括号内调用eval函数得到值
}
else if( *p == ')' )
show_error("( and ) not matched.",p);
else if(isNumeric(*p)) // 如果是简单数字
{
sscanf(p,"%lf",&temp); // 利用sscanf扫入数字
while(isNumeric(*p)) p++; // 指针偏移
p--;
}
else
show_error("character not recognized.",p);
if(needop)
show_error("missing operator.",p);
if(op=='+') // 根据操作符入stack
push(&t,temp);
else if(op=='-')
push(&t,-temp);
else if(op=='*')
{
temp2 = pop(&t);
temp2 *= temp;
push(&t,temp2);
}
else if(op=='/')
{
if(temp == 0)
show_error("divided by zero.",p);
temp2 = pop(&t);
temp2 /= temp;
push(&t,temp2);
}
cantakeadd = cantakemul = 1;
needop = 1;
needoperand = 0;
}
}
if(needoperand)
show_error("missing operand here.",p);
temp = 0;
while(!empty(&t)) // 统计stack内所有数之和
{
temp2 = pop(&t);
temp += temp2;
}
return temp; // 返回总和
}
int main()
{
int len;
char temp;
double result;
while(1)
{
len = 0;
while(temp = _getch())
{
if(temp=='\b')
{
printf("\b \b");
len--;
}
else if(temp=='=' || temp=='\n' || temp=='\r')
{
putchar(10);
break;
}
else if(temp<=0)
{
temp = _getch();
}
else
{
s[len++] = temp;
putchar(temp);
}
}
s[len] = 0;
p = s + strlen(s) - 1;
while(p >= s && *p == ' ')
{
*p = 0;
p--;
}
p = s;
while(*p == ' ') p++;
if(strcmp(p,"")==0) continue;
len = strlen(p);
try
{
result = eval(p,p+len);
printf("%s = %g\n\n",p, result);
} catch(...)
{
printf("Calculation interupted.\n");
}
}
}
有个课程设计的,功能都几强大,除了你说的功能外还支持括号及其嵌套。要吗?