こんなもんじゃろ
$ gcc -o calc1 calc1.c -lm
$ ./calc1
止めたい時はqを入力するかCTRL+C
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/*
逆ポーランド式のパージング
参考資料:
技術評論社 河西 朝雄 著
C言語による はじめてのアルゴリズム入門
2718円+税
P252〜254より引用
技術評論社 奥村晴彦 著
C言語による最新アルゴリズム事典 2330円+税
P72〜73より引用・改変
*/
int ch,ii,jj;
char p[100]="",polish[100];
void readch();
void expression();
void term();
void factor();
double v[50];
int sp1;
main(){
int i,m,flg;
START:
ii=0;jj=0;
printf("(q)Button is quit; calc: ");
scanf("%s",p);
if(p[0]=='q'||p[0]=='Q') exit(1);
do{
readch();
expression();
} while(ch!='\0');
p[ii]='\0';
polish[jj]='\0';
sp1=0;flg=0;
for(i=0;i<jj;i++){
printf("%c",polish[i]);
if(isdigit(polish[i])){
if(flg==0){
flg=1;
v[++sp1]=polish[i]-'0';
}
else v[sp1]=v[sp1]*10+polish[i]-'0';
}
else if(polish[i]=='@') flg=0;
else{
flg=0;
switch(polish[i]){
case '+': v[sp1-1]+=v[sp1]; break;
case '-': v[sp1-1]-=v[sp1]; break;
case '*': v[sp1-1]*=v[sp1]; break;
case '/': v[sp1-1]/=v[sp1]; break;
case '^': v[sp1-1]=pow(v[sp1-1],v[sp1]); break;
case '%': m=(int)v[sp1-1]%(int)v[sp1];
v[sp1-1]=(double)m;
break;
}
sp1--;
}
}
printf("\n%s=%f\n",p,v[1]);
goto START;
}
void readch(){
if((ch=p[ii++])=='\0') return;
}
void expression(){
term();
while(1){
if(ch=='+'){ readch(); term(); polish[jj++]='+'; }
else if(ch=='-'){ readch(); term(); polish[jj++]='-'; }
else break;
}
}
void term(){
factor();
while(1){
if(ch=='*'){ readch(); factor(); polish[jj++]='*'; }
else if(ch=='/'){ readch(); factor(); polish[jj++]='/'; }
else if(ch=='^'){ readch(); factor(); polish[jj++]='^'; }
else if(ch=='%'){ readch(); factor(); polish[jj++]='%'; }
else break;
}
}
void factor(){
if(ch=='('){
while(ch!=')'&&ch!='\0'){
readch();
expression();
}
if(ch==')') readch();
else puts("error2");
}
else if(isdigit(ch)){
while(isdigit(ch) && ch!='\0'){
polish[jj++]=ch;
readch();
}
polish[jj++]='@';
}
else puts("error1");
}
0 件のコメント:
コメントを投稿