Thread: RPN calculator, identify different terms in a string.

  1. #1
    Registered User
    Join Date
    May 2016
    Posts
    1

    Question RPN calculator, identify different terms in a string.

    Hello, I'm coding a Reverse polish notation calculator in C. For now, i have the push/pop stack code completed and now I need to code the data you give to the program to evaluate. Here is my idea:

    The user types a sequence of numbers, operators and constants separated by a space, like this: 3 2 + pi -. The program should recognize each term of this string and return the value of the expression.

    This is my code for now:
    Code:
    #include <stdio.h>#include<conio.h>
    #include<string.h>
    #include <stdlib.h>
    #define MAX 40
    int top, status;
    
    
    /*push*/
    void push (char stack[], int x)
    {
         if (top == (MAX-1))
            status = 0;
        else
        {   status = 1;
            top=top+1;
            stack [top] = x;
        }
    }
    
    
    /*pop*/
    int pop (char stack[])
    {
        int ret;
        if (top == -1)
        {   ret = 0;
        status = 0;
        }
        else
        {   status = 1;
        ret = stack [top];
        top=top-1;
        }
    return ret;
    }
    int main()
    {
        int i, nombre,x1,x2;
    
    
    char inicial[MAX];
    char final1[MAX];
    
    
        printf(" introduce the RPN expression");
        fgets(inicial, MAX, stdin);
    
    
        for (i=0; i>=MAX; i++)
        if (isdigit(inicial[i]));
        {
        sscanf(inicial[i], "%s", inicial[i]);
        nombre=atoi(inicial[i]);
        push(final1, nombre);
        }
        if(isspace(inicial[i]));
        break;
        }
        if(ispunct(inicial[i]));
        {
            x1=pop(inicial);
            x2=pop(inicial);
        }
        if(inicial[i])=='+';
        push(final1, x2+x1);
        if(inicial[i])=='-';
        push(final1, x2-x1);
        if(inicial[i])=='*';
        push(final1, x2*x1);
        if(inicial[i])=='/'
        push(final1, x2/x1);
    As you can see I have problems when I put multiples If and with the isspace function. What I want to do, is that when the program detects that the position i from the string inicial is a blank space, ignore it and jump to the next position. How can i do that?

    The other thing I want to ask you is how to make the program realise the different types of ispunct and act differently according to that type (+, -, *, and /).

    I hope you understood the idea of what I want to do, please ask me if I didn't explain myself well.

    Thank you in advnace

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    If I were going to write an RPN calculator I would not actually write my own parser for it unless I needed to convert from infix notation.

    It would be beneficial to break up the string into pieces before you try to calculate:
    Code:
    char **
    rpn_break(char *eq, char **stack, int *n)
    {
        int size = 6; // stack size guess.
     
        stack = malloc(size * sizeof(*stack));
        if (stack == NULL)
            return NULL;
     
        char *token;
        int i = 0;
     
        for (token = strtok(eq, "\n\t "); token != NULL; token = strtok(NULL, "\n\t "))
        {
            if (i == size) {
                char *temp;
     
                size *= 2;
                temp = realloc(stack, size);
                if (temp == NULL)
                {
                    free(stack);
                    return NULL;
                }
                stack = temp;
            }
     
            stack[i++] = token;
        }
     
        *n = i;
        return stack;
    }
     
    int 
    main(void) {
        int size = 0;
        char **stack = NULL;
        char eq[BUFSIZ];
     
        puts("enter RPN equation here:");
        fgets(eq, sizeof eq, stdin);
        stack = rpn_break(eq, stack, &size);
     
        for (int i = 0; i < size; i++) {
            printf("stack[%d] = \"%s\"\n", i, stack[i]);
        }
     
        free(stack);
        stack = NULL;
     
        return 0;
    }
    We can reasonably expect the result on your example to be
    stack[0] = "3"
    stack[1] = "2"
    stack[2] = "+"
    stack[3] = "pi"
    stack[4] = "-"
    The code that you currently have is exceptionally brittle, because the stack is just a string, so every operand has to fit in a character. This just isn't a reasonable expectation. The constant pi can't be stored as a single character, and neither can multiple digit numbers.

    The other thing I want to ask you is how to make the program realise the different types of ispunct and act differently according to that type (+, -, *, and /).
    Well, if the tokens are strings, then strcmp(stack[i], foo) would return 0 for any string foo, like "-", "+", etc.

    I think push is coded incorrectly, as well. Variable top is initially 0, instead of -1 like you apparently expect in your code, so I would actually write something to the effect of:

    Code:
    int top = -1;
    
    void push(stack, x)
    {
       if (top == MAX - 1) 
       {
          status = 0;
       }
       else 
       {
          stack[++top] = x;
          status = 1;
       }
    }
    Now top always points to the first element in the stack instead of something else without wasting any stack space.
    Last edited by whiteflags; 05-19-2016 at 12:02 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 02-04-2012, 09:46 AM
  2. Replies: 3
    Last Post: 10-04-2010, 07:54 AM
  3. Replies: 7
    Last Post: 12-10-2007, 01:32 PM
  4. Terms used in C
    By lido in forum C Programming
    Replies: 12
    Last Post: 07-25-2003, 02:24 PM
  5. Terms
    By Drakon in forum Game Programming
    Replies: 7
    Last Post: 09-27-2001, 06:24 PM

Tags for this Thread