2018년 5월 25일 금요일

C language simple calculator source code (c언어 기본 계산기 코드)

// 2014.5.21 made by criny
// + - * / % 연산 가능
// 괄호 처리 가능
// 단항 - 연산자 가능

#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);
        }
    }
}

댓글 없음:

댓글 쓰기