Solved

Debug a small program

Posted on 2004-04-05
8
327 Views
Last Modified: 2010-04-15
////////why is the answer of expression wrong?Can anyone debug it for me?
/*****************************/
/* Student : Dang Tuan Anh   */
/* MSSV     :0212012         */
/* Class      : 2002CT/1     */
/*****************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
/* constants */
#define TRUE 1
#define FALSE 0

/* structure for stack */
typedef struct
{
     char data[20];  /* array to hold stack contents */
     int top;        /* top of the stack pointer */
} STACK;


/* function prototypes */
void initStack(STACK *stack);
void get_infix(char infix[]);
void convertToPostfix(char infix[], char postfix[]);
int isOperator(char c);
int pred_level(char ch);
void push(STACK *stack, char value);
char pop(STACK *stack);
char stackTop(STACK *stack);
int isEmpty(STACK *stack);
int isFull(STACK *stack);
void printResult(char infix[], char postfix[]);
void print_msg(void);
int evaluate_postfix(char postfix[]);
int tinh(char ,int ,int );

/* program entry point */
void main()
{
     char infix[20], postfix[20]="";

     /* convert from infix to postfix main function */
     convertToPostfix(infix, postfix);
     /* display the postfix equivalent */
     infix[strlen(infix)-1] = '\0';
     printResult(infix, postfix);
     printf("\nKet qua la`:%d",evaluate_postfix(postfix));
     getch();

}

/* initalise the stack */
void initStack(STACK *stack)
{
     stack->top = -1;  /* stack is initially empty */
}

/* get infix expression from user */
void get_infix(char infix[])
{
     printf("Enter infix expression:");
     fflush(stdin);
     gets(infix);

}

/* Ham chuyen tu infix sang postfix */
void convertToPostfix(char infix[], char postfix[])
{
     int i, length;
     int j=0;
     char top_ch;
     STACK stack;

     initStack(&stack); /* initialise stack */
     get_infix(infix);  /* get infix expression from user */
     length = strlen(infix);

     /* if strlen if infix is more than zero */
     if ( length )
     {
          push(&stack, '(');
          strcat(infix, ")");
          length++;

          for ( i=0; i<length; i++ )
          {
               /* if current operator in infix is digit */
               if ( isdigit(infix[i]) )
               {
                    postfix[j++] = infix[i];
               }
               /* if current operator in infix is left parenthesis */
               else if ( infix[i] == '(' )
               {
                    push(&stack, '(');
               }
               /* if current operator in infix is operator */
               else if ( isOperator(infix[i]) )
               {
                    while ( TRUE )
                    {
                         /* get tos */
                         top_ch = stackTop(&stack);

                         /* no stack left */
                         if ( top_ch == '\0' )
                         {
                              printf("\nInvalid infix expression\n");
                              print_msg();
                              exit(1);
                         }
                         else
                         {
                              if ( isOperator(top_ch) )
                              {
                                   if ( pred_level(top_ch) >= pred_level(infix[i]) )
                                        postfix[j++] = pop(&stack);
                                   else
                                        break;
                              }
                              else
                                   break;
                         }
                    }
                    push(&stack, infix[i]);
               }
               /* if current operator in infix is right parenthesis */
               else if ( infix[i] == ')' )
               {
                    while ( TRUE )
                    {
                         /* get tos */
                         top_ch = stackTop(&stack);

                         /* no stack left */
                         if ( top_ch == '\0' )
                         {
                              printf("\nInvalid infix expression\n");
                              print_msg();
                              exit(1);
                         }
                         else
                         {
                              if ( top_ch != '(' )
                              {
                                   postfix[j++] = top_ch;
                                   pop(&stack);
                              }
                              else
                              {
                                   pop(&stack);
                                   break;
                              }
                         }
                    }
                    continue;
               }
          }
     }

     postfix[j] = '\0';
}
///////////////////////////////////
//Ham evaluate a postfix
int evaluate_postfix(char postfix[])
{   int operand1,operand2;
    int i=0;
    int kq;
    STACK operand_stack;
    initStack(&operand_stack);
    while (postfix[i]!=NULL)
      {if (isdigit(postfix[i])) push(&operand_stack,postfix[i]);
       else
         {  operand1=(int)pop(&operand_stack);
            operand2=(int)pop(&operand_stack);
            kq=tinh(postfix[i],operand1,operand2);
            push(&operand_stack,(char)kq);
         }
       i++;
      }
  return pop(&operand_stack);
}

/* determine if c is an operator */
int isOperator(char c)
{
     if ( c == '+' || c == '-' || c == '*' ||
           c == '/' )
     {
          return TRUE;
     }
     else
          return FALSE;
}

/* determine precedence level */
int pred_level(char ch)
{
     if ( ch == '+' || ch == '-' )
          return 1;
     else if ( ch == '^' )
          return 3;
     else
          return 2;
}

/* push a value on the stack */
void push(STACK *stack, char value)
{
     if ( !(isFull(stack)) )
     {
          (stack->top)++;
          stack->data[stack->top] = value;
     }
}

/* pop a value off the stack */
char pop(STACK *stack)
{
     char ch;

     if ( !(isEmpty(stack)) )
     {
          ch = stack->data[stack->top];
          (stack->top)--;
          return ch;
     }
     else
          return '\0';
}

/* return the top value of the stack without popping the stack */
char stackTop(STACK *stack)
{
     if ( !(isEmpty(stack)) )
          return stack->data[stack->top];
     else
          return '\0';
}

/* determine if stack is empty */
int isEmpty(STACK *stack)
{
     /* empty */
     if ( stack->top == -1 )
          return TRUE;
     /* not empty */
     else
          return FALSE;
}

/* determine if stack is full */
int isFull(STACK *stack)
{
     /* full */
     if ( stack->top == 19 )
          return TRUE;
     /* not full */
     else
          return FALSE;
}
///////////////////////////////////////
int tinh(char operator1,int operand1,int operand2)
{ switch(operator1)
  {  case'+':return (operand1+operand2);
     case'-':return (operand1-operand2);
     case'*':return (operand1*operand2);
     case'/':return (int)(operand1/operand2);

  }
}

/* display the result postfix expression */
void printResult(char infix[], char postfix[])
{
     /*system("cls");*/
     printf("\n\n");
     printf("Infix notation  : %s\n", infix);
     printf("Postfix notation: %s\n\n", postfix);

}

/* print exit message */
void print_msg(void)
{
     printf("Nhan phim bat ki de thoat:");
     fflush(stdin);
     getchar();
}
0
Comment
Question by:squallanh
8 Comments
 
LVL 1

Accepted Solution

by:
while_true earned 100 total points
Comment Utility
Your pop-function returns characters, not integers! Caused by this, if you type 1+2 (what is evaluated correctly to 12+) your evaluation function is calculating 99, that is the addition of of the ascii-codes of '1' (49) and '2' (50).
Change your pop-function to type int and return atoi( ch ) then it will work correctly.
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 70 total points
Comment Utility
Hi,

U didnt need to open a new question.U could ask this in ur old thread only.

We dont do ur homework but we're always glad to help u out in it when ur stuck somewhere

I am happy to see that u tried it urself.

Here are a few suggestions:

1. atoi can be used but atoi takes a char * as argument.
Its prototype is int atoi(const char *);
So,if ur calculator needs to work for single digits only,u can use atoi as follows:
char temp[2];
temp[0]=ch;
temp[1]='\0';
return atoi(temp);
Pls take note that the result of an operation can also be of more than one digit.

2. Don't use gets().Its dangerous to use.see the man pages for details.
use cin.getline()(if u want to allow spaces) or scanf()(no spaces,acts as a delimiter)
0
 
LVL 2

Expert Comment

by:Avik77
Comment Utility
check ur converttopostfix function.within the for loop did u check for the possibility of any symbols.
i.e INFIX : a+b
what do u do when 'a' and 'b' are scanned.

Avik.
0
 
LVL 2

Assisted Solution

by:Avik77
Avik77 earned 270 total points
Comment Utility
Ok ur working with chars . Now in ur postfix evaluation

int evaluate_postfix(char postfix[])
{   int operand1,operand2;
    int i=0;
    int kq;
    STACK operand_stack;
    initStack(&operand_stack);
    while (postfix[i]!=NULL)
      {if (isdigit(postfix[i])) push(&operand_stack,postfix[i]);
       else
         {  operand1=(int)pop(&operand_stack)-48;
            operand2=(int)pop(&operand_stack)-48;
            kq=tinh(postfix[i],operand1,operand2);
            push(&operand_stack,(char)kq);
         }
       i++;
      }
  return pop(&operand_stack);
}

operand1 and operand2 are taking the ascii value of ur digit. I have subtracted them by 48 ie ascii value of '0'.

Avik.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 2

Assisted Solution

by:Avik77
Avik77 earned 270 total points
Comment Utility
Again there are many problems like the in the postfix evaluation function push accepts a char value. what should it accept when u have -4 as an entry or a two digit number as an argument to push. My suggestions to u is to set up an integer stack structure that can manage ur evaluation function.
u can also use a simple int array and a top variable to use as a stack only for ur postfix evaluation
while (postfix[i]!=NULL)
      {
       if (isdigit(postfix[i])) {stack1[++top]=postfix[i]-48;}
       else {  operand1=stack1[top];top--;
                 operand2=stack1[top];top--;
                 kq=tinh(postfix[i],operand1,operand2);
                 stack1[++top]=kq;
         }
       i++;
      }
 return stack[top];
}

and remember in tinh()
it is always operand2 op operand1
so
int tinh(char operator1,int operand1,int operand2)
{ switch(operator1)
  {  case'+':return (operand2+operand1);
     case'-':return (operand2-operand1);
     case'*':return (operand2*operand1);
     case'/':return (int)(operand2/operand1);

  }
}

Hope now it will be fixed.
Avik.


0
 
LVL 2

Expert Comment

by:Avik77
Comment Utility
sorry, make it return stack1[top] , comment ur STACK declaration and its initialiser and declare int stack1[100] and a top variable.

Avik.
0
 
LVL 8

Assisted Solution

by:ssnkumar
ssnkumar earned 60 total points
Comment Utility
If you are dealing with integer arguments, then change the struct to:
typedef struct
{
     int data[20];  /* array to hold stack contents */
     int top;        /* top of the stack pointer */
} STACK;

Before putting the value into stack, convert it into int (or read as int itself) and push on the stack.

-ssnkumar
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 70 total points
Comment Utility
Here is how to implement a stack using Linked Lists.Try(if u want to extend ur program for multiple digits) implementing this in ur existing program.

struct node
{
 int data;
 struct node *next;
}*p;

void push(struct node *q,int d)
{
  struct node *temp;
  temp=p;
  p=malloc(sizeof(struct node));
  p->data=d;
  p->next=temp;
}

int pop(struct node *q)
{
 int n;
 struct node *temp;
 if(p==NULL) return NULL;
 else
 {
 n=p->data;
 p=p->next;
 }
 return n;
}

here p points to the start node.Inititially, p=NULL;
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now