简体   繁体   中英

Parsing strings of equations in c using scanf

I need to parse input from a user that could be any number of variations: 1+1 4( 3-0 ) =x 1*(3)-8

How do I do this using scanf to get the raw_input, then split out all of the different values and tell either if it is a string ie x = - () or a int?

This is what I was thinking

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

It takes a array of char and then I just need to split and convert into a single elements. What is the best way of doing the input and (splitting and converting)

Thanks

If you want to write your own code, the best way is to define your expression in form of a grammar. To easily parse the grammar, it's best to make it simple.

For example, to parse expressions in the form like this (1+(3*4+x)*y)+1, you could write such a grammar:

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

Then in your program, for every non-terminal in this grammar (the ones on the left of ->), you write one function, like this:

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;
    }
}

Similarly, Multiplication and RestOfMultiplication would be written as functions.

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;
    }
}

Where extract_int and extract_variable are two functions that take the expression and the position on it, go ahead while they are seeing a number (or a letter in the extract_variable function) they build the number (variable) from the expression string and return it, setting position to after where they finished.

Note: This is not code for copy paste. It is not complete and lacks sufficient error checking. Some details have been omitted and is offered as a solution to teach how simple parsing is done rather than easiest solution.

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

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

This is definitely not correct. raw_input is pointer that can hold an address. It isn't initialized and so it is pointing to garbage or to the worst it seems to point to a valid memory location. You cannot take input to it with actually pointing it to a valid memory location.

You need to malloc the bytes required and make the raw_input point to it. And then perform operation(s) on these memory locations.

You need a lexical analyzer and a parser. You may try lex and yacc, or their newer counterparts flex and bison.

You could use:

  • flex, the free lexer generator.
  • Per-string iterator. Just traverse all string and pick all the items you want. strtok() may be helpful here. Or make a big loop and just read things per-char until you have the whole token.
  • Regexes via re2c (that's what PHP use)

After you split the string into tokens, you will need to parse it. You will need yacc or a hand-made parser (those are usually recursive descent ).

Don't use scanf . Use getchar and apply the Shunting Yard Algorithm .

Use array and not pointers. If you cant use other libraries you can to look in side cstring

But it will be too long in your case

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM