📄 expression.cpp
字号:
/*
Expression.cpp
基于命令行的四则运算计算器
同时可以实现进制(Dec,Hex,Bin,Oct)之间的相互转换
为简约起见,我没有加入高精度运算的环节
*/
//By phoenixinter
//On 12/12/2004
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define STACKSIZE 100 //表达式的最长字符数
int topt=-1,topd=-1; //Stack Pointer
double opnd[STACKSIZE]; //数字栈
char oprt[STACKSIZE]; //符号栈
char expression[STACKSIZE]; //存储表达式
int ismistake=0; //判断输入的表达式是否有语法错误
double chiaus;
void convert();
void pushopnd(double x) //数字压栈
{
if(topd==STACKSIZE-1)
{
printf("Operand Stack overflow!\n");
exit(-1);
}
opnd[++topd]=x;
}
void pushoprt(char x) //符号压栈
{
if(topt==STACKSIZE-1)
{
printf("Operator Stack overflow!\n");
exit(-1);
}
oprt[++topt]=x;
}
double popopnd() //数字出栈
{
if(topd==-1)
{
printf("Operand Stack underflow!\n");
exit(-1);
}
return(opnd[topd--]);
}
char popoprt() //符号出栈
{
if(topt==-1)
{
printf("Operator Stack underflow!\n");
exit(-1);
}
return(oprt[topt--]);
}
double getopnd() //取得数字栈的栈顶元素
{
if(topd==-1)
{
printf("Operand Stack underflow!\n");
exit(-1);
}
return(opnd[topd]);
}
char getoprt() //取得符号栈的栈顶元素
{
if(topt==-1)
{
printf("Operator Stack underflow!\n");
exit(-1);
}
return(oprt[topt]);
}
char priority(char c1,char c2) //比较符号优先级
{
if((c1=='*'||c1=='/')&&(c2!='(')) return '>';
if((c1=='+'||c1=='-')&&(c2=='+'||c2=='-'||c2==')'||c2=='\0' )) return '>';
if((c1=='+'||c1=='-')&&(c2=='*'||c2=='/'||c2=='(')) return '<';
if((c1=='*'||c1=='/')&&(c2=='(')) return '<';
if(c1=='('&&c2!=')') return '<';
if(c1=='('&&c2==')') return '=';
if(c1==')') return '>';
if(c1=='\0'&&c2=='\0') return '=';
if(c1=='\0'&&c2!='\0') return '<';
}
double calculate(double a,char symbol,double b) //执行单个符号的计算
{
double result;
if(symbol=='+') result=a+b;
if(symbol=='-') result=a-b;
if(symbol=='*') result=a*b;
if(symbol=='/') result=a/b;
return result;
}
void initexpression()
{
printf("Please input an arithmetic expression.\n");
printf("Please don't input unwanted space or tab.\n");
printf("Press Enter to finish your input:\n");
scanf(" %s",expression);
}
void btod()
{
int isfrac=0;
char *p,s[20];
double power=1,value=0;
printf("Please input a binary:");
scanf(" %s",s);
p=s;
while(*p!='\0')
{
if(*p=='.') isfrac=1;
else if(isfrac==0)
{
if(*p=='1')value=value*2+1;
if(*p=='0')value=value*2;
}
else
{
power=power*2;
if(*p=='1')value=value+1.0/power;
}
p++;
}
chiaus=value;
printf("The decimal code is:");
printf("%f\n",value);
}
void otod()
{
int isfrac=0;
char *p,s[20];
double power=1,value=0;
printf("Please input a octal:");
scanf(" %s",s);
p=s;
while(*p!='\0')
{
if(*p=='.')
isfrac=1;
else if(isfrac==0)
value=value*8+(double)(*p-48);
else
{
power=power*8;
value=value+(double)(*p-48)/power;
}
p++;
}
chiaus=value;
printf("The decimal code is:");
printf("%f\n",value);
}
void htod()
{
int isfrac=0;
char *p,s[20];
double power=1,value=0;
printf("Please input a hexadecimal:");
scanf(" %s",s);
p=s;
while(*p!='\0')
{
if(*p=='.')
isfrac=1;
else if(isfrac==0)
{
if(*p>='0'&&*p<='9')
value=value*16+(double)(*p-48);
else if(*p>='A'&&*p<='F')
value=value*16+(double)(*p-55);
else value=value*16+(double)(*p-87);
}
else
{
power=power*16;
if(*p>'0'&&*p<='9')
value=value+(double)(*p-48)/power;
else if(*p>'A'&&*p<='F')
value=value+(double)(*p-55)/power;
else value=value+(double)(*p-87)/power;
}
p++;
}
chiaus=value;
printf("The decimal code is:");
printf("%f\n",value);
}
void dtob(double x)
{
int num,i,a[64];
long n,abn;
double m;
n=(long int)x;
m=x-(long int)x;
if(n>=0)abn=n;
else abn=-n;
for(i=0;i<16;i++)
{
if(abn%2==0) a[i]=0;
else a[i]=1;
abn=abn/2;
if(abn==1)
{
a[++i]=1;
num=i;
break;
}
}
printf("The binary code is:");
for(i=num;i>=0;i--)
printf("%d",a[i]);
if(m!=0)
{
for(i=num+1;i<=num+6;i++)
if(m*2>=1)
{
m=2*m-1;
a[i]=1;
}
else
{
m=m*2;
a[i]=0;
}
printf(".");
for(i=num+1;i<num+7;i++)
printf("%d",a[i]);
}
printf("\n");
}
void dtoo(double x)
{
int num,i,a[16];
long n,abn;
double m;
n=(long int)x;
m=x-(long int)x;
if(n>=0)abn=n;
else abn=-n;
for(i=0;i<16;i++)
{
if(abn%8==0)
a[i]=0;
else a[i]=abn%8;
abn=abn/8;
if(abn==0)
{
num=i;
break;
}
if(abn<8)
{
a[++i]=abn;
num=i;
break;
}
}
printf("The octal code is:");
for(i=num;i>=0;i--)
printf("%d",a[i]);
if(m!=0)
{
for(i=num+1;i<=num+5;i++)
if(m*8>=1)
{
a[i]=(int)(8*m);
m=8*m-(int)(8*m);
}
else
{
m=m*8;
a[i]=0;
}
printf(".");
for(i=num+1;i<num+5;i++)
printf("%d",a[i]);
}
printf("\n");
}
void dtoh(double x)
{
int num,i;
long n,abn,t;
double m;
char a[16];
n=(long int)x;
m=x-(long int)x;
if(n>=0)abn=n;
else abn=-n;
for(i=0;i<16;i++)
{
t=abn%16;
if(t==0) a[i]='0';
else if(t>=0&&t<=9)a[i]=(char)(abn%16+48);
else switch(t)
{
case 10:a[i]='A';break;
case 11:a[i]='B';break;
case 12:a[i]='C';break;
case 13:a[i]='D';break;
case 14:a[i]='E';break;
case 15:a[i]='F';
}
abn=abn/16;
if(abn==0){num=i;break;}
if(abn<16)
{
i++;
if(abn>0&&abn<=9)a[i]=(char)(abn%16+48);
else
{
switch(abn)
{
case 10:a[i]='A';break;
case 11:a[i]='B';break;
case 12:a[i]='C';break;
case 13:a[i]='D';break;
case 14:a[i]='E';break;
case 15:a[i]='F';
}
}
num=i;
break;
}
}
printf("The hexadecimal code is:");
for(i=num;i>=0;i--)
printf("%c",a[i]);
if(m!=0)
{
for(i=num+1;i<=num+4;i++)
if(m*16>=1)
{
t=(int)(16*m);
if(abn>=0&&t<=9)a[i]=(char)(t+48);
else switch(abn)
{
case 10:a[i]='A';break;
case 11:a[i]='B';break;
case 12:a[i]='C';break;
case 13:a[i]='D';break;
case 14:a[i]='E';break;
case 15:a[i]='F';
}
m=16*m-(int)(16*m);
}
else {m=m*16;a[i]=0;}
printf(".");
for(i=num+1;i<num+3;i++)
printf("%c",a[i]);
}
printf("\n");
}
double dtod(char s[])
{
int isfrac=0;
char *p;
double power=1,value=0;
p=s;
while(*p!='\0')
{
if(*p=='.') isfrac=1;
else if(isfrac==0)value=value*10+(double)(*p-48);
else
{
power=power*10;
value=value+(double)(*p-48)/power;
}
p++;
}
return(value);
}
int judge(char a,char b) //判断表达式相邻符号输入正误
{
if((a=='+'||a=='-'||a=='*'||a=='/'||a=='.')&&(b=='+'||b=='-'||b=='*'||b=='/'||b=='.'||b==')'||b=='\0'))return 1;
if((a=='(')&&(b==')'||b=='*'||b=='/'||b=='.'||b=='\0'))return 2;
if((a==')')&&(b=='.'||b=='('||(b>='0'&&b<='9')))return 3;
if(a>='0'&&a<='9'&&b=='(')return 4;
else return 0;
}
void check() //检查表达式拼写是否有误
{
int i,j=0,a=0,b=0,lparenth=0,rparenth=0;
char c,sign1,sign2;
c=expression[0];
sign1=c;
if(c>='0'&&c<='9'||c>='('&&c<='+'||c=='.'||c=='-'||c=='/');
else
{
ismistake=1;
printf("Error 1! Invalid charactor!\n");
goto end;
} // Error 1
if(c=='(') lparenth++;
if(c=='.'||c==')'||c=='*'||c=='/')
{
ismistake=1;
printf("Error 2! The first character cannot be '.',')','*','/'.\n");
goto end;
}// Error 2
for(i=1;c!='\0';i++)
{
c=expression[i];
if(c>='0'&&c<='9'||c>='('&&c<='+'||c=='.'||c=='-'||c=='/'||c=='\0');
else
{
ismistake=1;
printf("Error 1! Invalid charactor!\n");
goto end;
}
sign2=c;
j=judge(sign1,sign2);
switch(j)
{
case 0:
if(c=='.'&&b==0) a=1;
if(a==1&&c>='0'&&c<='9') b=1;
if(b==1&&c=='.')
{
ismistake=1;
printf("Error 3! more than one dots in a number.\n");
goto end;
}// Error 3
if(c=='+'||c=='-'||c=='*'||c=='/'||c==')')
{
a=0;
b=0;
}
if(c=='(')
lparenth++;
if(c==')')
rparenth++;
break;
case 1:
printf("Error 4! '+','-','*','/','.' cannot be put together or at the very end or before ')'.\n");// Error 4
ismistake=1;
goto end;
case 2:
printf("Error 5! '(' cannot be put at last or followed by ')','*','/','.'.\n");// Error 5
ismistake=1;
goto end;
case 3:
printf("Error 6! ')' cannot be followed by numbers and '('.\n");// Error 6
ismistake=1;
goto end;
case 4:
printf("Error 7! Numbers cannot be followed by '('.\n");// Error 7
ismistake=1;
goto end;
}
sign1=sign2;
}
if(lparenth!=rparenth)
{
ismistake=1;
printf("Error 8! The parenthesis are not matched\n");
}// Error 8
end:
if(ismistake==1)
printf("Error occurred! You should input arithmetic expression again!\n");
}
double evaluate() //计算表达式的值
{
double a,b,gd,tempresult;
char c,symbol,gt,temp[20];
int i=0,isfigure=0,issigned=0;
int j=0;
double number;
pushoprt('\0');
c=expression[0];
if(c=='+')c=expression[i++];
if(c=='-')pushopnd(0);
gt=getoprt();
while(c!='\0'||gt!='\0')
{
if(c>='0'&&c<='9'||c=='.')
{
isfigure=1;issigned=0;
temp[j++]=c;
c=expression[++i];
}
else
{
if(isfigure==1){temp[j]='\0';number=dtod(temp);pushopnd(number);}
isfigure=0;j=0;
if(c=='(')issigned=1;
if(c=='-'&&issigned==1)pushopnd(0);
if(c=='+'&&issigned==1)i++;
gt=getoprt();
switch(priority(gt,c))
{
case'<':
{pushoprt(c);c=expression[++i];break;}
case'=':
{symbol=popoprt();c=expression[++i];break;}
case'>':
{symbol=popoprt();b=popopnd();a=popopnd();
tempresult=calculate(a,symbol,b);
pushopnd(tempresult);break;}
}
}
gt=getoprt();
}
gd=getopnd();
return(gd);
}
void menu()
{
printf(" *****************************************************************\n");
printf(" * Command Menu *\n");
printf(" * 1. Command Menu [menu] *\n");
printf(" * 2. Expression Evaluation [run] *\n");
printf(" * 3. Number Base Conversion [convert] *\n");
printf(" * 4. Quit this program [quit] *\n");
printf(" * 5. Clear the screen [cls] *\n");
printf(" * *\n");
printf(" *****************************************************************\n");
}
void quit()
{
printf("******************************************************\n");
printf("** Thanks for using my program! **\n");
printf("** I wrote this program just for my DS homework.:) **\n");
printf("** There might be some errors and bugs in my code. **\n");
printf("** If you have any problems, **\n");
printf("** write to phoenixinter@126.com **\n");
printf("** Or contact me by QQ:50147231 **\n");
printf("** ^_^ Bye for now~ **\n");
printf("******************************************************\n");
}
void run()
{
double result;
loop:
initexpression();
check();
if(ismistake==0)
{
result=evaluate();
printf("VALUE = %f\n",result);
}
else
{
ismistake=0;
goto loop;
}
}
void main()
{
char k,key[8];
loop1:
menu();
printf("Your Command:");
scanf(" %s",key);
while(strcmp(key,"run")!=0)
{
if(strcmp(key,"menu")==0)
menu();
else if(strcmp(key,"convert")==0)
convert();
else if(strcmp(key,"cls")==0)
system("cls");
else if(strcmp(key,"quit")==0)
{
quit();
exit(0);
}
else
printf("Wrong Command!\n");
printf("Your Command:");
scanf(" %s",key);
}
loop2:
run();
printf("Continue to calculate or back to command menu?\n");
printf("Continue--->'C',Back--->B (C/B)?");
loop3:
scanf(" %c",&k);
if(k=='c'||k=='C')
{
ismistake=0;
goto loop2;
}
else if(k=='b'||k=='B')
goto loop1;
else
{
printf("Wrong Command!\nInput again(C/B)?");
goto loop3;
}
}
void convert()
{
int choice;
char k;
double dec;
float deci;
loop1:
printf(" *****************************************************************\n");
printf(" * Convert Menu *\n");
printf(" * <Binary> <Octal> *\n");
printf(" * [1]. binary to octal [4]. octal to binary *\n");
printf(" * [2]. binary to decimal [5]. octal to decimal *\n");
printf(" * [3]. binary to hexadecimal [6]. octal to hexadecimal *\n");
printf(" * *\n");
printf(" * <Decimal> <Hexadecimal> *\n");
printf(" * [7]. decimal to binary [10].hexadecimal to binary *\n");
printf(" * [8]. decimal to octal [11].hexadecimal to octal *\n");
printf(" * [9]. decimal to hexadecimal [12].hexadecimal to decimal *\n");
printf(" * *\n");
printf(" *****************************************************************\n");
printf("Please enter your choice:[ ]\b\b\b");
loop2:
scanf(" %d",&choice);
if(choice>0&&choice<13);
else
{
printf("Invalid choice! choose again:[ ]\b\b\b");
goto loop2;
}
loop3:
switch(choice)
{
case 1:btod();dtoo(chiaus);break;
case 2:btod();break;
case 3:btod();dtoh(chiaus);break;
case 4:otod();dtob(chiaus);break;
case 5:otod();break;
case 6:otod();dtoh(chiaus);break;
case 7:printf("Please input a decimal:");scanf(" %f",&deci);dec=(double)deci;dtob(dec);break;
case 8:printf("Please input a decimal:");scanf(" %f",&deci);dec=(double)deci;dtoo(dec);break;
case 9:printf("Please input a decimal:");scanf(" %f",&deci);dec=(double)deci;dtoh(dec);break;
case 10:htod();dtob(chiaus);break;
case 11:htod();dtoo(chiaus);break;
case 12:htod();break;
}
printf("Continue to convert or Select a new mode or Back to command menu?\n");
printf("Continue--->C,Select--->S,Back--->B (C/S/B)?");
loop4:
scanf(" %c",&k);
if(k=='c'||k=='C')
goto loop3;
else if(k=='b'||k=='B')
main();
else if(k=='s'||k=='S')
goto loop1;
else
printf("Wrong Command!\nInput again(C/S/B)?");
goto loop4;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -