advena
advena

Reputation: 83

atof() assining 0 where needs to be a dobule

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.

Upvotes: 0

Views: 146

Answers (1)

Andro
Andro

Reputation: 2232

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.

Upvotes: 4

Related Questions