// + - * / % 연산 가능
// 괄호 처리 가능
// 단항 - 연산자 가능
#include
#include
#include
#define BUF_SIZE 500
#define TRUE 1
#define FALSE 0
int prio[128] = {
['('] = 0,
['+'] = 1,
['-'] = 1,
['*'] = 2,
['/'] = 2,
['%'] = 2
};
void do_cal(char *cmd, int * result){
char *p = 0;
char postfix[BUF_SIZE] = {0,};
int stack[50];
int stack_index = 0;
char c;
char tmp[10];
int a, b;
// [1] convert Infix to Postfix
while((p = strtok(!p ? cmd : 0, "|"))){
if(p[0] >= '0' && p[0] <= '9'){
strcat(postfix, p);
strcat(postfix, "|");
}
else if(p[0] == '('){
stack[stack_index++] = '(';
}
else if(p[0] == ')'){
while((c = stack[--stack_index]) != '('){
sprintf(tmp, "%c|", c);
strcat(postfix, tmp);
}
}
else{ // if etc operator
while(prio[stack[stack_index - 1]] >= prio[*p]){
c = stack[--stack_index];
sprintf(tmp, "%c|", c);
strcat(postfix, tmp);
}
stack[stack_index++] = p[0];
}
}
printf("*postfix : %s\n", postfix);
// [2] calculate Postfix`Notation
stack_index = 0;
p = 0;
while((p = strtok(!p ? postfix : 0, "|"))){
if(p[0] >= '0' && p[0] <= '9'){
stack[stack_index++] = atoi(p);
}
else{
b = stack[--stack_index];
a = stack[--stack_index];
switch(p[0]){
case '+':
stack[stack_index++] = a + b;
break;
case '-':
stack[stack_index++] = a - b;
break;
case '*':
stack[stack_index++] = a * b;
break;
case '/':
stack[stack_index++] = a / b;
break;
case '%':
stack[stack_index++] = a % b;
}
}
}
*result = stack[stack_index-1];
}
int trim_cmd(char *cmd){
char tmpcmd[BUF_SIZE] = {0,};
char outcmd[BUF_SIZE] = {0,};
char *p = cmd;
int i = 0;
int flag = 0; // to process solo '-'
// [1] trim and wrap command with '(' and ')'
tmpcmd[i++] = '(';
while(*p != 0){
if(*p != ' ')
tmpcmd[i++] =*p;
p++;
}
tmpcmd[i++] = ')';
// [2] make pure cmd
p = tmpcmd;
i = 0;
while(*p != 0){
if(*p >='0' && *p <= '9'){
outcmd[i++] = *p;
}
else if(*p == '+' || *p == '-' || *p == '*' || *p == '/'
|| *p == '%' || *p == '(' || *p == ')'){
if(flag){
outcmd[i++] = '|';
outcmd[i++] = ')';
outcmd[i++] = '|';
flag = 0;
}
if(*p == '-' &&
(*(p-1) == '(' || *(p-1) == '+' || *(p-1) == '-'
||*(p-1) == '*' || *(p-1) == '/' || *(p-1) == '%')){
outcmd[i++] = '|';
outcmd[i++] = '(';
outcmd[i++] = '|';
outcmd[i++] = '0';
flag = 1;
}
outcmd[i++] = '|';
outcmd[i++] = *p;
outcmd[i++] = '|';
}
else{
printf("command error\n");
return FALSE;
}
p++;
}
if(flag){
outcmd[i++] = '|';
outcmd[i++] = ')';
outcmd[i++] = '|';
flag = 0;
}
strcpy(cmd, outcmd);
return TRUE;
}
int main(void) {
char cmdbuf[BUF_SIZE];
int result;
while (1) {
printf("(input) ");
scanf("%[^\n]", cmdbuf);
__fpurge(stdin);
if(trim_cmd(cmdbuf) != FALSE){
printf("*tirmed cmd : %s\n", cmdbuf);
do_cal(cmdbuf, &result);
printf("*result : %d\n", result);
}
}
}
댓글 없음:
댓글 쓰기