简易四则运算计算器

简易计算器重制版,原版.

修复:区分不了运算符和数字的 bug。
待完善:支持负数运算。

#include <stdio.h>

#define MAX_LENG 100

double calc(char str[]);
void rpn(char str[], char rpn[]);
int isDigit(char c);
int isOperator(char c);
double atof(char s[]);
double peek();
void push(double n);
double pop();
int compare(char c1, char c2);
int type(char c);

int main() {
    printf("%.6f", calc("3.3 * (3 + 9) - 12"));
}

double calc(char str[]) {
    int i, j, c;
    double temp, a, b;
    char num[MAX_LENG];

    char rpn_expre[MAX_LENG];
    rpn(str, rpn_expre);

    for (i = 0; rpn_expre[i] != '\0'; i++) {
        num[0] = c = rpn_expre[i];
        j = 0;
        if (c == ' ' || c == '\t') {
            continue;
        }
        if (isDigit(c)) {
            while (isDigit(num[++j] = c = rpn_expre[++i])) {}
            if (c == '.') {
                while (isDigit(num[++j] = c = rpn_expre[++i])) {}
            }			
            num[j] = '\0';
            push(atof(num));
            i--;
            continue;
        } 
        switch (c) {
            case '+':
                push(pop() + pop()); 
                break;
            case '-':
                temp = pop();
                push(pop() - temp);
                break;
            case '*':
                push(pop() * pop());
                break;
            case '/':
                temp = pop();
                if (temp == 0.0) {
                    printf("error: zero divisor\n");
                } else {
                    push(pop() / temp);
                }
                break;
            case '%':
                b = pop();
				a = pop();
				if (b == 0.0) {
					printf("error: zero divisor\n");
				} else {
					push(a - (int)(a/b) * b);
				}
                break;
            default:
                printf("error: unknown operator %c\n", c);
                break;
        }
    }
    return pop();
}

void rpn(char str[], char rpn[]) {
    int i, j, c;
    for (i = j = 0; str[i] != '\0'; i++) {
        rpn[j] = c = str[i];
        // 跳过空格
        if (c == ' ' || c == '\t') {
            continue;
        }
        // 读取数字填充到 rpn
        if (isDigit(c)) {
            while (isDigit(rpn[++j] = c = str[++i])) {}
            if (c == '.') {
                while (isDigit(rpn[++j] = c = str[++i])) {}
            }			
            rpn[j++] = ' ';
            rpn[j] = '\0';
            i--;
            continue;
        } 

        // 读取运算符填充到 rpn
        if (c == ')') {
            while ((rpn[j] = pop()) != '(') {j++;};
        } else if (c == '(') {
            push(c);
        } else if (isOperator(c)) {
			if (peek() == '(' || peek() == 0.0) {
				push(c);
			} else if (compare(c, peek()) > 0) {
                push(c);
            } else {
                while (peek() != 0.0 && peek() != '(') {
                    rpn[j++] = pop();
                }
                push(c);
            }
        } else {
            printf("error: unknown operator %c\n", c);
        }
        rpn[j] = '\0';
    }

    // 栈中元素全部出栈,填充到 rpn
    while ((rpn[j] = pop()) != 0.0) {j++;};
    rpn[j] = '\0'; 	
}

int isDigit(char c) {
    return c >= '0' && c <= '9';
}
int isOperator(char c) {
    switch (c) {
        case '+' :
        case '-' :
        case '*' :
        case '/' :
        case '%' :
            return 1;
    }
    return 0;
}

double atof(char s[]) {
    int sign = 1;
    int i = 0;
    switch (s[0]) {
        case '-':
            sign = -1;
            i = 1;
            break;    
        case '+':
            i = 1;
            break;
    }
    double n = 0.0;
    while (s[i] >= '0' && s[i] <= '9') {
        n = 10 * n + (s[i] - '0');
        i++;
    }
    if (s[i] == '.') {
        i++;
    }
    double power = 1.0;
    while (s[i] >= '0' && s[i] <= '9') {
        n = 10 * n + (s[i] - '0');
        i++;
        power *= 10;
    }
    return sign * n/power;
}

int size = 0;
double val[MAX_LENG];
double peek() {
    if (size > 0) {
        return val[size-1];
    } else {
        printf("error: stack empty\n");
        return 0.0;
    }
}
void push(double n) {
    if (size < MAX_LENG) {
        val[size++] = n;
    } else {
        printf("errof: stack full, can't push %g\n", n);
    }
}
double pop() {
    if (size > 0) {
        return val[--size];
    } else {
        printf("error: stack empty\n");
        return 0.0;
    }
}

int compare(char c1, char c2) {
    return type(c1) - type(c2);
}
int type(char c) {
    switch (c) {
        case '+':
        case '-':
            return 0;
        case '*':
        case '/':
        case '%':
            return 1;
        default:
            printf("error: unknown operator %c\n", c);
            return -1;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值