fails when popping a string

Hey, we are working on a program to evaluate strings to make expressions for example: 3 4 5 + *
This when properly evaluated will make the expression (3*(4+5))
to do this we need to make a stack and push in the numbers. take the top of the stack for the right hand operand and then take that result and that becomes the top of the stack.

My code will get the (4+5) but then when it tries to pull that and do the *3 it crashes.
unfortunately it should look like this:
Expression: 3 4 5 + *
Evaluates to: 27
Infix: ( 3 * ( 4 + 5 ) )

Can you help me figure out what I am doing wrong?
code for stack.h:
// Stack.h A linked stack template.
// Lab 15. Students have to write the functions


//------------------------------------------------------------------------------
// Node is specific to Stack, so it's part of this file
#include <iostream>
using namespace std;
template <typename T>
class Node
{
public:
Node();
Node(T);

T data;
Node *next;
};

template <typename T>
Node<T>::Node()
{
next = NULL;
}

template <typename T>
Node<T>::Node(T d)
{
data = d;
next = NULL;
}
// end of Node class template
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// Beginning of Stack class template

template <typename T>
class Stack
{
public:
Stack();
void push(T);
bool pop(T&);
bool isEmpty();
private:
Node<T> *tos;
};

template <typename T>
Stack<T>::Stack()
{
tos = NULL;
}

template <typename T>
void Stack<T>::push(T x)
{
cout<<"push: "<<x<<endl;
Node<T> *t = new Node<T>(x);
(*t).next=tos;
tos=t;

}

template <typename T>
bool Stack<T>::pop(T &x)
{
if(isEmpty())
return false;
x=(*tos).data;
cout<<"pop: "<<x<<endl;
Node<T> *t=tos;
tos = (*tos).next;
delete t;
return true;
}

template <typename T>
bool Stack<T>::isEmpty()
{
return(tos==NULL);
}

// End of Stack class template
//-----------------------------------------------------------------------------


Code for lab 4.h:

// Lab 4. Extract lexical units from strings
// students have to write getNextLex() function

#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;


//------------------------------------------------------------------------------
// determine if c is a digit character
bool isDigit(char c)
{
return '0' <= c && c <= '9' || c=='.';
}

//------------------------------------------------------------------------------
// determine if c is a multiplication operator
bool isMulop(char c)
{
return (c=='*' || c=='/');
}

//------------------------------------------------------------------------------
// determine if c is an addition operator
bool isAddop(char c)
{
return c=='+' || c=='-';
}

//------------------------------------------------------------------------------
//==============================================================================

void extractFirst(string &s, string &t){
t=t+s.substr(0,1);
s=s.substr(1);
}



code for main program:

#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include "stack.h"
#include <sstream>
#include "lab 4.h"
using namespace std;
bool operate(Stack<string> stk,float &total, string c,Stack<float> stkf){
cout<<c<<endl;
string rOp;//string of right op
string lOp;//...left
float frOp;//float of right op
float flOp;//...left
string t;
if(!stk.pop(rOp)||!stkf.pop(frOp)){//crashes here when popping string
cout<<"Error: Right operand cannot be found"<<endl<<endl;
//cout<<"============================================"<<endl;
return 0;
}
if(!stk.pop(lOp)||!stkf.pop(flOp)){
cout<<"Error: Left operand cannot be found"<<endl<<endl;
//cout<<"============================================"<<endl;
return 0;
}
cout<<"left and right popped"<<endl;
if(c=="+"){
total=total+flOp+frOp;//make total
t="( "+lOp+" + "+rOp+" )";//make string
stk.push(t);//push string for infix on top for next right op
stkf.push(total);//push float for total on top for next right op
return 1;
}
else if(c=="-"){//same as +
total=total+flOp-frOp;
t="( "+lOp+" - "+rOp+" )";
stk.push(t);
stkf.push(total);
return 1;
}
else if(c=="*"){//...
total=total+(flOp*frOp);
t="( "+lOp+" * "+rOp+" )";
stk.push(t);
stkf.push(total);
return 1;
}
else if(c=="/"){//...
total=total+(flOp/frOp);
t="( "+lOp+" / "+rOp+" )";
stk.push(t);
stkf.push(total);
return 1;
}
}
bool evaluate(string s, float &total, Stack<string> stk, Stack<float> stkf){
//float total=0;
//cout<<"''"<<s[0]<<"''"<<endl;
//Stack<string> stk;
while(s.length()>0){
//cout<<"'"<<s[0]<<"'"<<endl;
string t="";//reset token
while(s[0]==' ')//trim spaces
s=s.substr(1);
if(isDigit(s[0])){//make digit token
while(isDigit(s[0])){
extractFirst(s, t);
}
stk.push(t.c_str());//push string for infix
stkf.push(atof(t.c_str()));//push number for float
}
else if(isMulop(s[0])||isAddop(s[0])){//calculate total and infix strings
extractFirst(s, t);
if(!operate(stk, total, t,stkf))
return 0;
}
}//string length is now 0
//check to see if there is something left in the stack that isn't the total.
//if there is something left in the stack that isn't just the total then
//that means that there are more operators for the numbers to get used up
//haven't tested code below
/*float test, next;
stk.pop(test);//top pop should be total
if(test!=total&&stk.pop(next)){//if pop succeeds again then
cout<<"Operator expected!"<<Endl;<<endl;
return 0;
}
else{
stk.push(test);//doesn't fail, put total back on top
return 1
}*/
}

bool fileOpen(string name){
Stack<string> stk;//string stack for infix
Stack<float>stkf;//float stack for total
string expr;//string for expression
ifstream file;
file.open(name.c_str());//open file
if(!file){
cout<<"File '"<<name<<"' not found!"<<endl;
return 0;
}
else{
while(file){
float total=0;//reset total for new expression line
getline(file,expr);
for(int i=0; i<expr.length(); i++){//trim after % for comments
if (expr[i]=='%')
expr=expr.substr(0,i);
}
cout<<"Expression: "<<expr<<endl;//expression without comments
if(evaluate(expr,total,stk,stkf)){
string infix;//string for infix, should be top of string stack
//cout<<"Popping infix..."<<endl;
stk.pop(infix);//pop infix string DOES NOT WORK
cout<<" Evaluates to: "<<total<<endl;
cout<<" Infix: "<<infix<<endl<<endl;
}
}
return 1;
}
}

int main(int argc, char *argv[]){
string filename;
cout<<"File name: ";
cin>>filename;
fileOpen(filename);
system("PAUSE");
return EXIT_SUCCESS;
}
Topic archived. No new replies allowed.