2

我正在寻找一个可以将字符串表达式评估为整数的函数,例如 fe:

10/2+4*3-(12+5); //Equals 0

进入一个int值为的类型的对象0

复杂操作的功能会更好,即使这不是小时的需要:

2^(1/2)-99

标准 C 库(C89、C90,如果已编译)中是否定义了任何此类定义?

有没有具有这种功能的非标准库?

表达式支持的字符越多越好。

但即使是像 +,-,*,/,() 这样的基本操作也可以。

4

3 回答 3

4

标准 C 库(C89、C90,如果已编译)中是否定义了任何此类定义?

不,甚至在最新的 C11 或 C18 标准库中也没有。

有没有具有这种功能的非标准库?

我也找不到。你必须编写自己的函数来完成它。

也许在第一步扫描字符串并将其中的每个值存储到一个单独的字符串中。

正如我在评论中已经建议的那样,strtol用于将11字符串中的整数值转换为 type 的值int。您可能需要使用它。在库中还有一个atoi将字符串中的整数值转换为 an的函数,int但此函数更容易出错,不应使用。

算术运算符也应存储在单独的字符串中,但稍后由自制例程进行评估。

但是可以在此处找到很好的示例和建议,其中向用户询问了类似(如果不相同)的问题:

C:将数学表达式字符串转换为带有结果的int

于 2020-02-16T09:48:58.703 回答
3

标准 C 库中没有计算算术表达式的函数。这是结果evald函数的快速而肮脏的实现double。它支持 5 种经典的二元运算+, -,*和与 的幂运算/,可以处理任何深度的括号,但一元和需要更多的工作。%^+-

很容易转换为仅整数的算术。

这是代码:

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

double evald(const char *s, char **endp) {
    struct operand {
        double val;
        int op, prec;
    } stack[4], *sp, x;
    char *p;

    for (sp = stack;;) {
        if (*s == '(') {
            x.val = evald(s + 1, &p);
            s = p;
            if (*s == ')')
                s++;
        } else {
            x.val = strtod(s, &p);
            s = p;
        }
        while (isspace((unsigned char)*s))
            s++;
        switch (x.op = *s++) {
        case '^': x.prec = 3; break;
        case '*':
        case '/':
        case '%': x.prec = 2; break;
        case '+':
        case '-': x.prec = 1; break;
        default:  x.prec = 0; x.op = 0; s--; break;
        }
        while (sp > stack && x.prec <= sp[-1].prec) {
            switch ((--sp)->op) {
            case '^': x.val = pow(sp->val, x.val); break;
            case '*': x.val = sp->val * x.val; break;
            case '/': x.val = sp->val / x.val; break;
            case '%': x.val = fmod(sp->val, x.val); break;
            case '+': x.val = sp->val + x.val; break;
            case '-': x.val = sp->val - x.val; break;
            }
        }
        if (!x.op) break;
        *sp++ = x;
    }
    if (endp) *endp = (char *)s;
    return x.val;
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        for (int i = 1; i < argc; i++) {
            printf("%s -> %.17g\n", argv[i], evald(argv[i], NULL));
        }
    } else {
        char buf[100];
        for (;;) {
            printf("eval> ");
            fflush(stdout);
            if (!fgets(buf, sizeof buf, stdin) || (buf[0] == 'q' && buf[1] == '\n'))
                break;
            printf(" -> %.17g\n", evald(buf, NULL));
        }
    }
    return 0;
}
于 2020-02-16T12:03:21.223 回答
1

有没有具有这种功能的非标准库?

GNU bison就有这样一个例子。bison是一个解析器生成器,是一个生成 C 文件的免费软件工具。

你也可以在你的应用程序中使用和嵌入Lua。它是开源的,所以你应该研究它的源代码。Lua 主要使用标准 C99 编码。

您可以编写自己的递归下降解析器,这很简单。

您可以考虑在您的应用程序中嵌入GNU GuilePython

当然,您应该使用比过时的 MS-DOS(或其FreeDOS替代品)更好的操作系统。我想到了Debian 。

您可以使用tinycc,它有一个libtcc类似于您需要的库 ( ),您可以研究它的源代码。

您需要阅读有关解析和编译的教科书。想到了龙书。或者至少阅读关于parsinglexing的维基百科页面。

于 2020-02-17T13:30:10.570 回答