使用scanf解析c中的方程组

时间:2011-09-13 14:36:24

标签: c scanf

我需要解析用户的输入,这些输入可以是任意数量的变体: 1 + 1 4(3-0)= x 1 *(3)-8

如何使用scanf获取raw_input,然后拆分所有不同的值并告诉它是否是字符串,即x = - ()或int?

这就是我的想法

    char * raw_input;
    scanf("%s",raw_input);

它需要一个char数组,然后我只需要拆分并转换为单个元素。做输入和(拆分和转换)的最佳方式是什么

由于

7 个答案:

答案 0 :(得分:4)

如果您想编写自己的代码,最好的方法是以语法的形式定义表达式。为了轻松解析语法,最好将其简化。

例如,要解析像这样(1 +(3 * 4 + x)* y)+1的形式的表达式,你可以编写这样的语法:

Expression -> Addition | null
Addition -> Multiplication RestOfAddition
RestOfAddition -> null | + Addition
Multiplication -> Element RestOfMultiplication
RestOfMultiplication -> null | * Element
Element -> number | variable | ( Expression )

然后在你的程序中,对于这个语法中的每个非终端(左边的那些 - >),你编写一个函数,如下所示:

ExpTree *Expression(char *exp, int *position)
{
    if (exp[*position])
    {
        ExpTree *node = malloc(sizeof(*node));
        node->type = LAMBDA;
        node->value = 0;
        return node;
    }
    else
        return Addition(exp, position);
}

ExpTree *Addition(char *exp, int *position)
{
    ExpTree *node = malloc(sizeof(*node));
    node->type = ADDITION;
    node->left = Multiplication(exp, position);
    node->right = RestOfAddition(exp, position);
    return node;
}

ExpTree *RestOfAddition(char *exp, int *position)
{
    ExpTree *node;
    if (exp[*position] == '+')
    {
        ++*position;
        return Addition(exp, position);
    }
    else
    {
        ExpTree *node = malloc(sizeof(*node));
        node->type = LAMBDA;
        node->value = 0;
        return node;
    }
}

同样,MultiplicationRestOfMultiplication将被写为函数。

ExpTree *Element(char *exp, int *position)
{
    if (exp[*position] == '(')
    {
        ExpTree *node;
        ++*position;
        node = Expression(exp, position);
        if (!exp[*position] != ')')
             printf("Expected ) at position %d\n", *position);
        else
             ++*position;
        return node;
    }
    else if (exp[*position] == ')')
    {
        printf("Unexpected ) at position %d\n", *position);
        return NULL;
    }
    else if (exp[*position] >= '0' && exp[*position] <= '9')
    {
        ExpTree *node = malloc(sizeof(*node));
        node->type = INTEGER;
        node->value = extract_int(exp, position);
        return node;
    }
    else if ((exp[*position] >= 'a' && exp[*position] <= 'z') ||
             (exp[*position] >= 'A' && exp[*position] <= 'Z') ||
             exp[*position] == '_')
    {
        ExpTree *node = malloc(sizeof(*node));
        node->type = VARIABLE;
        node->value = extract_variable(exp, position);
        return node;
    }
    else
    {
        printf("Warning: unexpected character %c in location %d\n", exp[*position], *position);
        return NULL;
    }
}

extract_intextract_variable是两个函数,它们接受表达式和位置,在它们看到一个数字(或extract_variable函数中的一个字母)时继续它们从表达式字符串构建数字(变量)并将其返回,将位置设置为完成后的位置。

注意:这不是复制粘贴的代码。它不完整,缺乏足够的错误检查。一些细节已被省略,并作为一种解决方案提供,以教授如何进行简单的解析而不是最简单的解决方案。

答案 1 :(得分:0)

您可能需要tokenize表达式,然后应用规则来确定表达式是否有效。

答案 2 :(得分:0)

char * raw_input;
scanf("%s",raw_input);

这绝对不正确。 raw_input是可以保存地址的指针。它没有初始化,所以它指向垃圾或最坏似乎指向有效的内存位置。您无法将输入实际指向有效的内存位置。

您需要malloc所需的字节,并使raw_input指向它。然后在这些内存位置上执行操作。

答案 3 :(得分:0)

你需要一个词法分析器和一个解析器。你可以试试lex和yacc,或者他们的新同行flex和bison。

答案 4 :(得分:0)

您可以使用:

  • flex,free lexer generator。
  • 每个字符串迭代器。只需遍历所有字符串并选择所需的所有项目。 strtok()可能会对您有所帮助。或者做一个大循环,然后只读取每个字符的内容,直到你拥有整个令牌。
  • regex通过re2c(这就是PHP使用的)

将字符串拆分为标记后,您需要解析它。您将需要yacc或手工制作的解析器(通常是recursive descent)。

答案 5 :(得分:0)

请勿使用scanf。使用getchar并应用Shunting Yard Algorithm

答案 6 :(得分:-1)

使用数组而不是指针。如果您无法使用其他库,则可以查看cstring

但是你的情况会太久了