一个C语言命令行计算器

超级厉害(bushi

0.序言

咱们在很多时候,都会在各种地方,看到各种算式。
计算这些算式对于我们小学数学没学好(BUSHI)的程序员们来说,简直是折磨。。。
因此,我就在开发正经项目的空闲时间,写了这个计算器。

用法:直接输“12+(5*7)”之类的表达式(不省略乘号)。图看不太清,请放大后查看。

仓库:

看看看看吧

可以试试:

1+1
3445667*345*(567+567)-12345
2/0 #if use GCC, it will be #INF, and I don’t know any thing else#

!!!!!一定要一个一个输入!

1.代码

请先看下面的源代码:

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

typedef struct Node {
char kind; // 'v' for value, 'o' for operator
    union {
        double value;
        struct {
            char op;
            struct Node *left;
            struct Node *right;
        } oper;
    };
} Node;

Node *expression();
Node *term();
Node *factor();
void match(char expected);
double evaluate(const Node *n);
void free_node(Node *node);
void skip_whitespace();

char *input;
int pos = 0;

Node *new_node_value(double val) {
    Node *node = malloc(sizeof(Node));
    node->kind = 'v';
    node->value = val;
    return node;
}

Node *new_node_operator(char op, Node *left, Node *right) {
    Node *node = malloc(sizeof(Node));
    node->kind = 'o';
    node->oper.op = op;
    node->oper.left = left;
    node->oper.right = right;
    return node;
}

void match(char expected) {
    skip_whitespace(); // Ensure we skip any whitespace before matching
    if (input[pos] == expected) {
        pos++;
    } else {
        fprintf(stderr, "Syntax error: expected '%c' at position %d\n", expected, pos);
        exit(EXIT_FAILURE);
    }
}

void skip_whitespace() {
    while (isspace(input[pos])) {
        pos++;
    }
}

Node *expression() {
    Node *t = term();
    skip_whitespace();
    while (input[pos] == '+' || input[pos] == '-') {
        char op = input[pos++];
        Node *t2 = term();
        t = new_node_operator(op, t, t2);
        skip_whitespace();
    }
    return t;
}

Node *term() {
    Node *f = factor();
    skip_whitespace();
    while (input[pos] == '*' || input[pos] == '/') {
        char op = input[pos++];
        Node *f2 = factor();
        f = new_node_operator(op, f, f2);
        skip_whitespace();
    }
    return f;
}

Node *factor() {
    skip_whitespace();
    if (isdigit(input[pos]) || input[pos] == '.') {
        char *end;
        double val = strtod(&input[pos], &end);
        pos = end - input; // Update the position after parsing the number
        return new_node_value(val);
    } else if (input[pos] == '(') {
        pos++; // Consume '('
        Node *e = expression();
        match(')'); // Match and consume ')'
        return e;
    } else {
        fprintf(stderr, "Syntax error: unexpected character '%c' at position %d\n", input[pos], pos);
        exit(EXIT_FAILURE);
    }
}

double evaluate(const Node *n) {
    switch (n->kind) {
    case 'v':
        return n->value;
    case 'o':
        switch (n->oper.op) {
        case '+':
            return evaluate(n->oper.left) + evaluate(n->oper.right);
        case '-':
            return evaluate(n->oper.left) - evaluate(n->oper.right);
        case '*':
            return evaluate(n->oper.left) * evaluate(n->oper.right);
        case '/':
            return evaluate(n->oper.left) / evaluate(n->oper.right);
        default:
            fprintf(stderr, "Syntax error: unknown operator '%c'\n", n->oper.op);
            exit(EXIT_FAILURE);
        }
        break;
    default:
        fprintf(stderr, "Syntax error: unknown node kind '%c'\n", n->kind);
        exit(EXIT_FAILURE);
    }
}

void free_node(Node *node) {
    if (node != NULL) {
        if (node->kind == 'o') {
            free_node(node->oper.left);
            free_node(node->oper.right);
        }
        free(node);
    }
}

int main() {
    char exp_str[256];
    printf("Enter an expression: ");

    if (fgets(exp_str, sizeof(exp_str), stdin) != NULL) {
        // Remove trailing newline character if present
        if (exp_str[strlen(exp_str) - 1] == '\n') {
            exp_str[strlen(exp_str) - 1] = '\0';
        }

        input = exp_str;
        Node *e = expression();
        printf("Result: %g\n", evaluate(e));
        free_node(e);
    }

    return 0;
}

看看各位能不能看懂?

各位自己编译一下用吧~

2.申明

MIT License

Copyright (c) 2024 Chenyun Zhang

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.MIT License

Copyright (c) 2024 Chenyun Zhang

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

了解 Clouds 的更多信息

订阅后即可通过电子邮件收到最新文章。


《“一个C语言命令行计算器”》 有 2 条评论

  1. 看不懂根本看不懂,班长你有也太牛了C0C佩服

    1. 我把你加成订阅者吧

留下评论

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理