首页 > 解决方案 > 解析简单的数学表达式

问题描述

我正在尝试使用命令行输入编写一个简单的数学表达式解析器。表达式将仅包含 +-*/ 操作,并且从左到右进行评估。

#include <stdio.h>
#include <stdlib.h>

//does not work for double digit inputs
int main (int argc, char *argv[]) 
{
    if (argc == 1) 
    {
        printf("\n======================================================== \n");
        printf("Invalid usage: <ProgramName>.exe <MathExpression:string> \n");
        printf("eg: 2+3/5*9 \n");
        printf("======================================================== \n");
        return 0;
    }

    char *expr = argv[1];

    float answer = (float)expr[0]-'0';

    for (int i = 2; i < strlen(expr); i+=2) {
        if (expr[i-1] == '+')
            answer += (float)expr[i]-'0';
        else if (expr[i-1] == '-')
            answer -= (float)expr[i]-'0';
        else if (expr[i-1] == '*')
            answer *= (float)expr[i]-'0';
        else if (expr[i-1] == '/')
            answer /= (float)expr[i]-'0';
    }

    printf("answer: %.2f", answer);

}

我编写的程序适用于单个数字输入,例如 3+4+5,但不适用于 10 以上的输入(例如 10+11+12)。知道如何解决这个问题吗?

标签: cparsing

解决方案


要将字符串中的数字解析为double,您可以使用strtod()

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    if (argc == 1) {
        printf("\n========================================================\n");
        printf("Invalid usage: <ProgramName>.exe <MathExpression:string>\n");
        printf("eg: 2+3/5*9\n");
        printf("========================================================\n");
        return 0;
    }

    char *expr = argv[1];

    double answer = strtod(expr, &expr);

    while (*expr) {
        if (*expr == ' ' || *expr == '\t')
            expr++;
        else if (*expr == '+')
            answer += strtod(expr + 1, &expr);
        else if (*expr == '-')
            answer -= strtod(expr + 1, &expr);
        else if (*expr == '*')
            answer *= strtod(expr + 1, &expr);
        else if (*expr == '/')
            answer /= strtod(expr + 1, &expr);
        else
            break;
    }
    printf("answer: %.2f\n", answer);
    return 0;
}

请注意,无效输入可能会产生令人惊讶的结果。这是检测无效输入的简单方法:

#include <stdio.h>
#include <stdlib.h>

double get_number(const char *expr, char **nextp) {
    double value = strtod(expr, nextp);
    if (expr == *nextp) {
        fprintf(stderr, "invalid input: %s\n", expr);
        exit(1);
    }
    return value;
}

int main(int argc, char *argv[]) {
    if (argc == 1) {
        printf("\n========================================================\n");
        printf("usage: <ProgramName>.exe <MathExpression:string>\n");
        printf("eg: '2+3/5*9'\n");
        printf("========================================================\n");
        return 0;
    }

    char *expr = argv[1];

    double answer = get_number(expr, &expr);

    while (*expr) {
        if (*expr == ' ' || *expr == '\t')
            expr++;
        else if (*expr == '+')
            answer += get_number(expr + 1, &expr);
        else if (*expr == '-')
            answer -= get_number(expr + 1, &expr);
        else if (*expr == '*')
            answer *= get_number(expr + 1, &expr);
        else if (*expr == '/')
            answer /= get_number(expr + 1, &expr);
        else {
            printf("invalid input: %s\n", expr);
            break;
        }
    }
    printf("answer: %.2f\n", answer);
    return 0;
}

推荐阅读