You have two operators, '*' and '+' in your expression to calculate multiplication. I have added & rearranged a bit of error checking,
int
performOp(const string& input, SLLNode& stack)
{
double fVal, sVal;
int result = 0;
if( stack.size < 2 )
{
cout << "Error: too few operands" << end;
stack.print();
return 1;
}
sVal = stack.popVal();
fVal = stack.popVal();
if(input == "+")
{
stack.pushVal(fVal + sVal);
}
else if(input == "-")
{
stack.pushVal(fVal - sVal);
}
else if(input == "*")
{
stack.pushVal(fVal * sVal); //problem was here
}
else if(input == "/" )
{
if(sVal == 0)
{
cout << "Error: Division by zero" << endl;
stack.print();
return 1;
}
stack.pushVal(fVal / sVal);
}
return 0;
}
Define a list node that contains head/tail, and counts the elements in your stack,
#include<iostream>
#include<string>
#include<sstream>
#include<iomanip>
using namespace std;
class SLLNode //single link list
{
public:
SLLNode *next;
double data;
SLLNode()
{
next = NULL;
data = 0;
}
void print()
{
SLLNode *node = NULL;
cout << "= " << data << endl << ">>";
}
};
Your stack implementation leaks memory, allocates unnecessary nodes, and is missing a couple of useful stack operations that will help you solve some of your problems. You need a destructor that empties your list in case you forget to empty it, and it would help to have a print the entire list. Anyway,
class SLList //single link list
{
SLLNode *head;
SLLNode *tail;
int _count;
public:
SLList()
{
head = NULL;
tail = NULL;
_count = 0;
}
~SLList()
{
while( !empty() ) { pop(); }
}
int size() { return _count; }
bool empty() { return (!head); return false; }
void push(double val)
{
SLLNode *node = new SLLNode;
node->data = val;
node->next = head;
++_count;
if(!tail) tail = node;
head = node;
}
double pop()
{
SLLNode *node = NULL;
if(!head) return 0;
node = head;
double val = node->data;
head = node->next;
--_count;
if(!head) tail = NULL;
delete node;
return val;
}
double tip()
{
SLLNode *node = NULL;
if(!head) return 0;
node = head;
double val = node->data;
return val;
}
void print()
{
SLLNode *node = NULL;
if(!head) return;
for( node=head; node; node=node->next )
node->print();
}
};
You might want to add more operators, extract that,
bool isOperator(const string& input);
int performOp(const string& input, SLList& stack);
static string BINOPS[] = {"+", "-", "*", "/"};
bool
isOperator(const string& input)
{
for(int i = 0; i < 4; i++) //should get size of BINOPS
{
if(input == BINOPS[i])
{
return true;
}
}
return false;
}
Check your stacksize prior to extracting items from your stack,
int
performOp(const string& input, SLList& stack)
{
double fVal, sVal;
int result = 0;
if( stack.size() < 2 )
{
cout<<"Error: too few operands"<<endl;
stack.print();
return 1;
}
sVal = stack.pop();
fVal = stack.pop();
if(input == "+")
{
stack.push(fVal + sVal);
}
else if(input == "-")
{
stack.push(fVal - sVal);
}
else if(input == "*")
{
stack.push(fVal * sVal);
}
else if(input == "/" )
{
if(sVal == 0)
{
cout << "Error: Division by zero" << endl;
stack.print();
return 1;
}
stack.push(fVal / sVal);
}
return 0;
}
You need some way to print your list. The forth language used ".", so here I have added a case to print the list using ".",
int
main()
{
string input;
SLList stack;
cout<<"::::::::::::::::RPN CALCULATOR:::::::::::::::::"<<endl;
cout<<"::TYPE IN A POSTFIX EXPRESSION OR 'q' TO QUIT::"<<endl;
cout<<":::::::::::::::::::::::::::::::::::::::::::::::"<<endl<<endl;
double num;
while(true)
{
cout << ">>";
cin >> input;
if(istringstream(input) >> num)
{
stack.push(num);
}
else if (isOperator(input))
{
performOp(input, stack);
}
else if (input == ".")
{
stack.print();
double val = stack.tip();
cout << "= " << val << endl << ">>";
}
else if (input == "q")
{
return 0;
}
else
{
cout << "Error: Invalid input" << endl;
}
}
}
I also cleaned up a couple of other errors.