このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。
ここで作ったプログラムは数字を読み込む部分が二箇所あるなど冗長でした。 1+2+3= など連続して演算子と数字を読み込むことを許し、マイナス記号の処 理も可能なように書き直すと次のようになります。
結果と読み込み中の数をそれぞれ result と num で表すことにします。 そして、演算子を op で表すことにします。 通常、電卓のように次の演算子を読み込んだ時や = を読み込んだ時に、計算 を行ないます。 例えば、 1 + 2 - 3 = であれば、 1 + 2 まで読み込み、次の - を読み込んだ 時に 1 + 2 を計算し、次の = を読み込んだ時に、 3 - 3 を計算します。 つまり、演算子を読み込んだ時の処理は次のようになります。
ここで問題なのは一番最初の数を読み込んで、次の演算子を読み込んだ時です。 この時、新しい result を計算するのに op には何も入ってません。 そこで、この場合は今読んだ数 num をそのまま result に入れることにしま す。
#include <stdio.h>
typedef enum {NUM, OP, END} STATE;
int result=0,num,sign;
char op=' ';
void calc(){
switch(op){
case ' ':
result = num*sign;
break;
case '+':
result += num*sign;
break;
case '-':
result -= num*sign;
break;
case '*':
result *= num*sign;
break;
case '/':
result /= num*sign;
break;
}
}
main(){
char c;
STATE s=OP;
while((c=getchar())!=EOF){
switch(s){
case OP:
if((c>='0')&&(c<='9')){
num=c-'0';
sign=1;
s=NUM;
}else if(c=='-'){
num=0;
sign=-1;
s=NUM;
}
break;
case NUM:
if((c>='0')&&(c<='9')){
num*=10;
num+=c-'0';
s=NUM;
}else if((c=='+')||(c=='-')||(c=='*')||(c=='/')){
calc();
op=c;
s=OP;
}else if(c=='='){
calc();
printf("result = %d\n",result);
return 0;
}
break;
}
}
}