-1

I made a C program to evaluate a postfix expression. The output is wrong. I have added print messages at various places to see where Iam going wrong. Turns out at the 4th or 5th line of the for loop body. I can't understand why it is happening.

 #include <stdio.h>
 #include <string.h>

  char exp[20];
 int stck[15];
 int tos = -1;

 int isEmpty() {
   if (tos == -1)
     return 1;
   return 0;
 }

 int isFull() {
   if (tos == 9)
     return 1;
   return 0;
 }

 int pop() {
   if (!(isEmpty()))
     return stck[tos--];
   else
     printf("Underflow\n");
 }

 void push(int c) {
   if (!(isFull()))
     stck[++tos] = c;
   else
     printf("Overflow\n");
 }

 int isOperator(char c) {
   if (c == '+' || c == '-' || c == '/' || c == '%' || c == '*')
     return 1;
   return 0;
 }

 main() {
   int i, a, b, c;
   printf("Enter the expression\n");
   gets(exp);
   for (i = 0; exp[i] != '\0'; i++) {
     printf("Current symbol is %c\n", exp[i]);
     if (!(isOperator(exp[i]))) {
       push((int) exp[i]);
       printf("Pushed %d into the stack\n", stck[tos]);
     } else {
       b = pop();
       a = pop();
       printf("Value of a and b are : %d and %d \n", a, b);
       if (exp[i] == '+')
         c = a + b;
       if (exp[i] == '-')
         c = a - b;
       if (exp[i] == '*')
         c = a * b;
       if (exp[i] == '/')
         c = a / b;
       if (exp[i] == '%')
         c = a % b;
       push(c);
       printf("C pushed. top of stack is now %d\n", stck[tos]);
     }
   }
   printf("The value of expression is: %d\n", pop());
 }
kiran Biradar
  • 12,700
  • 3
  • 19
  • 44
  • 1
    "The output is wrong" can you include in your question the precise output you receive and the expected output? – erik258 Jan 19 '19 at 18:51
  • 2
    Don't use `gets` [why-is-the-gets-function-so-dangerous-that-it-should-not-be-used](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used). – kiran Biradar Jan 19 '19 at 18:52
  • regarding: `#include < stdio.h >` Most compilers will mark this statement as an error due to the spaces inside the '<' and '>' Suggest removing those spaces – user3629249 Jan 19 '19 at 18:54
  • regarding: `char exp[20];` The 'exp()' is a built-in function. so the compiler will output a warning about the misuse of that built-in function – user3629249 Jan 19 '19 at 18:56
  • 1
    regarding: ` main() {` there are only two valid signatures for the `main()` function and they both have a return type of `int` – user3629249 Jan 19 '19 at 18:57
  • 1
    regarding: ` int pop() { if (!(isEmpty())) return stck[tos--]; else printf("Underflow\n"); }` the signature indicates a return type of `int`, but the 'else' code block does not return anything. – user3629249 Jan 19 '19 at 18:58
  • when compiling, always enable the warnings, then fix those warnings. ( for `gcc`, at a minimum use: `-Wall -Wextra -Wconversion -pedantic -std=gnu11` ) Note other compilers use different options to perform the same functionality – user3629249 Jan 19 '19 at 19:01
  • OT: for ease of readability and understanding: 1) separate code blocks `for` `if` `else` `while` `do...while` `switch` `case` `default` via a single blank line 2) when working with a variable width font, 2 space indents will shrink to 1/2 char width total. Suggest each indent level be 4 spaces. 3) variable (and parameter) names should indicate `content` or `usage` (or better, both) Names like 'a' 'b' 'c', etc are meaningless, even in the current context – user3629249 Jan 19 '19 at 19:06

2 Answers2

0

One problem here.

push((int) exp[i]);

You are pushing ASCII value instead of digits here.

What you want is

   push(exp[i]-'0'); // Converts ASCII to digit.
kiran Biradar
  • 12,700
  • 3
  • 19
  • 44
0

Krati, the evaluated expression is wrong because of push((int)exp[i]). This converts the char into its ASCII equivalent which is wrong. Please modify your code to `push(exp[i] - '0') which converts char to its equivalent number.

E.g.'1' - 49(ASCII value). Hence it will be evaluated to 49 - 48(ASCII of '0') = 1

Note: The code written doesn't support numbers > 9. You can do it this way.

  1. Consider each character as an operand and read its value before pushing. Expression: ab*c+ (here a, b, c are operands. If the character is not an operator consider it as an operand) You can use the following implementation with numbers > 9 also
#include<stdio.h>
#include<string.h>
char exp[20];
int stck[15];
int tos=-1;
int isEmpty()
{
    if(tos==-1)
        return 1;
    return 0;
}
int isFull()
{
    if(tos==9)
        return 1;
    return 0;
}
int pop()
{
    if(!(isEmpty()))
        return stck[tos--];
    else
        printf("Underflow\n");
}
void push(int c)
{
    if(!(isFull()))
        stck[++tos]=c;
    else 
        printf("Overflow\n");
} 
int isOperator(char c)
{ 
    if(c=='+' || c=='-' || c=='/' || c=='%' || c=='*' )
        return 1; 
    return 0; 
} 
void main() 
{ 
    int i,a,b,c, operand; 
    printf("Enter the expression: ");
    gets(exp); 
    for(i=0;exp[i]!='\0';i++) 
    {
        //printf("Current symbol is %c\n",exp[i]); 
        if(!(isOperator(exp[i]))) 
        { 
            printf("Enter '%c' value:", exp[i]);
            scanf("%d", &operand);
            push(operand);
            printf("Pushed %d into the stack\n",stck[tos]);
        } 
        else 
        { 
            b=pop(); 
            a=pop();
            printf("Value of a and b are : %d and %d \n",a,b);
            if(exp[i]=='+')
                c=a+b; 
            if(exp[i]=='-')
                c=a-b; 
            if(exp[i]=='*') 
                c=a*b; 
            if(exp[i]=='/')
                c=a/b; 
            if(exp[i]=='%') 
                c=a%b; 
            push(c); 
            printf("C pushed. top of stack is now %d\n",stck[tos]); 
        }
    } 
    printf("The value of expression is: %d\n",pop());
    getchar();
}