0

I'm trying to write my school assignment of rpn clalculator with providing expression by command line. Ex ./calc 2 + 5 \* sin 78

My idea is to use the struct data type to keep the number value or the operator type. Here is the main to clarify all:

#include <stdlib.h>
#include <math.h>
#include <string.h>


enum OPERATORS {val, PLUS, MINUS, MULTI, DIV, SIN, COS};
typedef struct value {

    double number;
    enum OPERATORS oper;
};


void get_the_onp(char *expression[], int length);


int main(int argc, char* argv[]) {

    double result;
    int i;
    printf("Number of arguments: %d\n", argc);


    get_the_onp(argv, argc);
    //result = equation(argv, argc);

    //printf("Result is: %f", result);
    return 0;
}

When I run the get_the_onp() function the atof() isn't working as I suspect. Here is the get_the_onp():

void get_the_onp(char* expression[], int length) {

    int i, j, k; //iterators i for expression; j for numbers; k for operators
    char *current;
    struct value values[length];


    for (i=1; i<length; i++) {
        current = expression[i];
        //printf("%f\n", atof(expression[i]));
        if (atof(current) != 0 && current != '0') {
            //printf("Inside if: %f\n", atof(current));
            values[i-1].number = (double) atof(current);
            values[i-1].oper = val;
        }

        else{
            switch(current[0]){

                case '+':
                    //values[i].number = NULL;
                    values[i-1].oper = PLUS;
                    break;
                case '-':
                    //values[i].number = NULL;
                    values[i-1].oper = MINUS;
                    break;
                case '*':
                    //values[i].number = NULL;
                    values[i-1].oper = MULTI;
                    break;
                case '/':
                    //values[i].number = NULL;
                    values[i-1].oper = DIV;
                    break;
                case 's':
                    //values[i].number = NULL;
                    values[i-1].oper = SIN;
                    break;
                case 'c':
                    //values[i].number = NULL;
                    values[i-1].oper = COS;
                    break;
            }
        }
    }

    //tester
    for (i=0; i<length; i++) {
            //if (values[i].oper != val)
                printf("Operator: %d\n", values[i].oper);

                printf("Number is: %d\n", values[i].number);
    }


    return;

}

The output for the example expression is:

Number of arguments: 7
Operator: 0
Number is: 2147483636
Operator: 1
Number is: 2147483636
Operator: 0
Number is: 2147483636
Operator: 3
Number is: 2147483636
Operator: 5
Number is: 2147483636
Operator: 0
Number is: 2147483636
Operator: -2072959800
Number is: 2147483626

I guess that there is something with the pointer current but I've no idea where to follow now.

advena
  • 83
  • 13
  • 2
    `current != '0'` is not correct. You are comparing pointer (`char*`) to non-pointer (`char`). – user694733 May 23 '14 at 07:34
  • this here `./calc 2 + 5 \* sin 78` is not correct rpn syntax. picture rpn as a stack where numbers are pushed on the stack and whenever an operator (or function like sin) is pushed it two elements (or one in the case of sin) from the stack and pushes the result. `2 +` would not work. – AndersK May 23 '14 at 07:47
  • Yeah I know that now after creating the `struct values[]` array I want to deal with rnp :) – advena May 23 '14 at 08:09
  • `for (i=0; i `for (i=0; i – BLUEPIXY May 23 '14 at 08:51

1 Answers1

4

The problem is right here:

printf("Number is: %d\n", values[i].number);

values.number is of type double (64 bit), but you are printing it as an int (32 bit) which invokes undefined behaviour.

Andro
  • 2,232
  • 1
  • 27
  • 40