Search code examples
c++while-loopstackinfix-notation

Infix equation solver c++ while loop stack


Im creating an infix problem solver and it crashes in the final while loop to finish the last part a of the equations.

I call a final while loop in main to solve whats left on the stack and it hangs there and if i pop the last element from the stack it will leave the loop and return the wrong answer.

//
//
//
//
//
#include <iostream>
#include<stack>
#include<string>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <sstream>
using namespace std;
#define size 30
int count=0;
int count2=0;
int total=0;
stack< string > prob;
char equ[size];
char temp[10];
string oper;
string k;
char t[10];
int j=0;
char y;


   int solve(int f,int s, char o)
   {
  cout<<"f="<<f<<endl;
  cout<<"s="<<s<<endl;
  cout<<"o="<<o<<endl;
  int a;
  if (o== '*')//checks the operand stack for operator
  {
    cout << f << "*" << s << endl;
    a= f*s;
  }
  if (o == '/')//checks the operand stack for operator
  {
    cout << f << "/" << s << endl;
    if(s==0)
    {
      cout<<"Cant divide by 0"<<endl;
    }
    else
      a= f/s;
  }
  if (o == '+')//checks the operand stack for operator
  {
    cout << f << "+" << s << endl;
    a= f+s;
  }
  if (o == '-')//checks the operand stack for operator
  {
    cout << f << "-" << s << endl;
    a= f-s;
  }
  return a;
}



int covnum()
{
  int l,c;
  k=prob.top();
  for(int i=0;k[i]!='\n';i++)t[i]=k[i];
  return l=atoi(t);
}


char covchar()
{
  k=prob.top();
  for(int i=0;k[i]!='\n';i++)t[i]=k[i];
  return t[0];
}


void tostring(int a)
{
  stringstream out;
  out << a;
  oper = out.str();
}


void charstack(char op)
{
  oper=op;
  prob.push(oper);
}


void numstack(char n[])
{
  oper=n;
  prob.push(oper);
}

void setprob()
{
  int f,s;
  char o;
  char t;
  int a;
  int i;
  t=covchar();
  if(ispunct(t))
  {
    if(t=='(')
    {
      prob.pop();
    }
    if(t==')')
    {
      prob.pop();
    }
    else if(t=='+'||'-')
    {
      y=t;
      prob.pop();
    }
    else if(t=='/'||'*')
    {
      y=t;
      prob.pop();
    }
  }
  cout<<"y="<<y<<endl;
  i=covnum();
  cout<<"i="<<i<<endl;
  s=i;
  prob.pop();
  t=covchar();
  cout<<"t="<<t<<endl;
  if(ispunct(t))
  {
    o=t;
    prob.pop();
  }
  i=covnum();
  cout<<"i="<<i<<endl;
  f=i;
  prob.pop();
  t=covchar();
  if (t=='('||')')
  {
    prob.pop();
  }
  a=solve(f,s, o);
  tostring(a);
  prob.push(oper);
  cout<<"A="<<prob.top()<<endl;
}


void postfix()
{
  int a=0;
  char k;
  for(int i=0;equ[i]!='\0';i++)
  {
    if(isdigit(equ[i]))//checks array for number
    {
      temp[count]=equ[i];
      count++;
    }
    if(ispunct(equ[i]))//checks array for operator
    {
      if(count>0)//if the int input is done convert it to a string and push to stack
      {
        numstack(temp);
        count=0;//resets the counter
      }
      if(equ[i]==')')//if char equals the ')' then set up and solve that bracket
      {
        setprob();
        i++;//pushes i to the next thing in the array
        total++;
      }
      while(equ[i]==')')//if char equals the ')' then set up and solve that bracket
      {
        i++;
      }
      if(isdigit(equ[i]))//checks array for number
      {
        temp[count]=equ[i];
        count++;
      }
      if(ispunct(equ[i]))
      {
        if(equ[i]==')')//if char equals the ')' then set up and solve that bracket
        {
          i++;
        }
        charstack(equ[i]);
      }
      if(isdigit(equ[i]))//checks array for number
      {
        temp[count]=equ[i];
        count++;
      }
    }
  }
}



int main()
{
  int a=0;
  char o;
  int c=0;

  cout<<"Enter Equation: ";
  cin>>equ;
  postfix();
  while(!prob.empty())
  {
    setprob();
    a=covnum();
    cout<<a<<" <=="<<endl;
    prob.pop();
    cout<<prob.top()<<"<top before c"<<endl;
    c=covnum();
    a=solve(c,a,y);
  }
  cout<<"Final Awnser"<<a<<endl;
  system ("PAUSE");
  return 0;
}

Solution

  • I see a number of things which all likely contribute to the issue of it not working:

    • There are no error or bounds checking. I realize that this is homework and as such may have specific requirements/specifications which eliminate the need for some checks, but you still need some to ensure you are correctly parsing the input. What if you exceed the array size of equ/tmp/t? What if your stack is empty when you try to pop/top it?
    • There are a few if statements that look like else if (t == '+' || '-') which most likely doesn't do what you want them to. This expression is actually always true since '-' is non-zero and is converted to a true value. You probably want else if (t == '+' || t == '-').
    • As far as I can tell you seem to skip parsing or adding '(' to the stack which should make it impossible for you to actually evaluate the expression properly.
    • You have a while loop in the middle of postfix() which skips multiple ')' but doesn't do anything.
    • Your code is very hard to follow. Properly naming variables and functions and eliminating most of the globals (you don't actually need most of them) would help a great deal as would proper indentation and add a few spaces in expressions.
    • There are other minor issues not particularily worth mentioning. For example the covchar() and covnum() functions are much more complex than needed.

    I've written a few postfix parsers over the years and I can't really follow what you are trying to do, which isn't to say the way you're trying is impossible but I would suggest re-examining at the base logic needed to parse the expression, particularly nested levels of brackets.