0
votes

Im writting a program (this is homework) to create an infix calculator in C using stacks. i came up with the following logic :

  • have two stacks : one for numbers , one for operators.
  • store input as a char string and then scan one char at a time , pushing each element into its proper stack.
  • ignore open parens , on encountering a closed paren : pop two numbers from numstack , and one operator from the opstack , calculate based on the popped values , and return the the answer.

    example : (1+(2*3)) should give 7

    but its not working. im getting garbage as output. this is my output :

    enter string to be evaluated (100 chars max): (1+1)
    
    string : (1+1)
    Length : 5
     reading : (
     reading : 1  pushing : 1
     reading : +  pushing : 43
     reading : 1  pushing : 1
     reading : )  popping : 1 popping : 1 popping : 431 + 302 = 303
     pushing : 303
    

    i dont understand why. some help would be great.


    my code :

    #include<stdio.h>
    #include<conio.h> // i **have to** use turbo c.
    #define LEN 25
    
    void push(int *stack  , int* top ,int item){
        printf(" pushing : %d ", item);
        stack[*top] = item;
        (*top)++;
    }
    
    int pop(int *stack , int* top){
        int temp;
        (*top)--;
        temp = stack[*top];
        printf(" popping : %d",temp); // this causing a dilemma while popping character operators.
        return temp;
    }
    
    void calc(int* numstack , int* numtop, int* opstack , int* optop){
        int num1,num2,ans;
        char sign;
    
        num1 = pop(numstack,numtop);
        num1 = pop(numstack,numtop);
    
        switch(pop(opstack,optop)){
            case '+' : ans = num1 + num2; sign = '+' ; break;
            case '-' : ans = num1 - num2; sign = '-' ; break;
            case '*' : ans = num1 * num2; sign = '*' ; break;
            case '/' : ans = num1 / num2; sign = '/' ; break;
        }
        printf("%d %c %d = %d \n",num1,sign,num2,ans);
        push(numstack,numtop,ans);
        while(getchar()!='\n'){} // cleanup stdin from any junk
    }
    
    int main(void){
        int optop = 0 , numtop = 0, i=0 , numstack[50] , opstack[30];
        char str[102], c;
        clrscr();
    
        // read and trim input evaluatioon string
        printf("enter string to be evaluated (100 chars max): ");
        fgets(str , 100 , stdin);
        while(str[i]!='\n'){ i++; }
        str[i] = '\0';
        printf("\nstring : %s \nLength : %d",str,i);
    
        i = 0;
        // evaluate
        while( (c=str[i]) !='\0'){
        printf("\n reading : %c ",str[i]);
        if(c=='('){ i++; continue; } // ignore open parens
        else if(c=='+'||c=='-'||c=='*'||c=='/') push(opstack,&optop,c);
        else if(c>=48 && c <=57) push(numstack,&numtop,(c-48));
        else if(c==')') calc(numstack , &numtop, opstack , &optop);
        else printf("\n%c is invalid..\n",c);
        i++;
        }
        printf("\nanswer is : %g",pop(numstack,&numtop));
        getch(); // again , *must use* turbo c
        return 0;
    }
    
  • 1
    sorry .. the post button got pressed before i wanted. updated the query. - Somjit
    Look up reverse polish notation - see en.wikipedia.org/wiki/Reverse_Polish_notation. There is algorithms to convert to it from infix notation - Ed Heal
    Ugh, hardcoding 48 and 57. Please use c >= '0' && c < '9'. - Barmar
    When I try compiling your code I get: calc.c:58: warning: format '%g' expects type 'double', but argument 2 has type 'int' - Barmar
    Ignoring open parens is clearly wrong, as 1*(2+3) and (1*2+3) will be parsed the same way. There's an extensive literature on how to parse expressions using an operator stack and an operand stack ... you should look into it. Note that your example (1+(2*3)) doesn't need parens at all, making it a very poor example. - Jim Balter

    1 Answers

    3
    votes

    Here's your problem:

    num1 = pop(numstack,numtop);
    num1 = pop(numstack,numtop);
    

    You're assigning to num1 both times, the first one should be num2.

    You also need to change the the final answer line to:

    printf("\nanswer is : %d\n",pop(numstack,&numtop));
    

    %g is for doubles, %d is for ints.