Reputation: 55
My task is to build a postfix calculator using a linked list to represent the stack. I have written the following code for the calculator, however I am receiving a compiler error that I do not understand. The error is coming from the postfixcalc.cpp file and is happening in the if-statement at operand2 = opers.getTop(op). The error reads, "value not ignored as it ought to be". I am using Dev-C++ and have never encountered this type of message. Any insight would be appreciated. Also, I can provide the StackP files if needed.
/** @file postfixcalc.h*/
#include "StackP.cpp"
#include <string>
using namespace std;
const int MAX_CHARS = 100;
class postfixcalc
{
public:
/** Default constructor. */
postfixcalc();
// postfixcalc operations:
void read();
void show();
int eval();
private:
string e;
Stack opers;
char stringInput[MAX_CHARS];
char *p;
};
/** @file postfixcalc.cpp*/
#include <iostream>
#include <cstring>
#include "postfixcalc.h"
using namespace std;
postfixcalc::postfixcalc()
{}
void postfixcalc::read()
{
cout << "Please enter a postfix expression: ";
getline(cin, e);
}//end read
void postfixcalc::show()
{
cout << e << endl;
}//end show
int postfixcalc::eval()
{
int operand1, operand2, result;
int op;
p = strtok(stringInput, " ");
while(p)
{
op = p[0];
if( op == '+' || op == '-' || op == '*' || op == '/')
{
operand2 = opers.getTop(op);
opers.pop();
operand1 = opers.getTop(op);
opers.pop();
switch(op)
{
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
case '/':
result = operand1 / operand2;
break;
}//end switch
opers.push(result);
}
else
{
opers.push(op);
}
p = strtok(NULL, " ");
}//end while
}//end eval
Here is the implementation of StackP
/** @file StackP.h */
#include "StackException.h"
typedef int StackItemType;
/** ADT stack - Pointer-based implementation. */
class Stack
{
public:
// Constructors and destructor:
/** Default constructor. */
Stack();
/** Copy constructor.
* @param aStack The stack to copy. */
Stack(const Stack& aStack);
/** Destructor. */
~Stack();
// Stack operations:
bool isEmpty() const;
void push(const StackItemType& newItem) throw(StackException);
void pop() throw(StackException);
void pop(StackItemType& stackTop) throw(StackException);
void getTop(StackItemType& stackTop) const
throw(StackException);
private:
/** A node on the stack. */
struct StackNode
{
/** A data item on the stack. */
StackItemType item;
/** Pointer to next node. */
StackNode *next;
}; // end StackNode
/** Pointer to first node in the stack. */
StackNode *topPtr;
}; // end Stack
/** @file StackP.cpp */
#include <cstddef> // for NULL
#include <new> // for bad_alloc
#include "StackP.h" // header file
using namespace std;
Stack::Stack() : topPtr(NULL)
{
} // end default constructor
Stack::Stack(const Stack& aStack)
{
if (aStack.topPtr == NULL)
topPtr = NULL; // original list is empty
else
{ // copy first node
topPtr = new StackNode;
topPtr->item = aStack.topPtr->item;
// copy rest of list
StackNode *newPtr = topPtr; // new list pointer
for (StackNode *origPtr = aStack.topPtr->next;
origPtr != NULL; origPtr = origPtr->next)
{ newPtr->next = new StackNode;
newPtr = newPtr->next;
newPtr->item = origPtr->item;
} // end for
newPtr->next = NULL;
} // end if
} // end copy constructor
Stack::~Stack()
{
// pop until stack is empty
while (!isEmpty())
pop();
// Assertion: topPtr == NULL
} // end destructor
bool Stack::isEmpty() const
{
return topPtr == NULL;
} // end isEmpty
void Stack::push(const StackItemType& newItem)
throw(StackException)
{
// create a new node
try
{
StackNode *newPtr = new StackNode;
// set data portion of new node
newPtr->item = newItem;
// insert the new node
newPtr->next = topPtr;
topPtr = newPtr;
}
catch (bad_alloc e)
{
throw StackException(
"StackException: push cannot allocate memory.");
} // try
} // end push
void Stack::pop() throw(StackException)
{
if (isEmpty())
throw StackException("StackException: stack empty on pop");
else
{ // stack is not empty; delete top
StackNode *temp = topPtr;
topPtr = topPtr->next;
// return deleted node to system
temp->next = NULL; // safeguard
delete temp;
} // end if
} // end pop
void Stack::pop(StackItemType& stackTop) throw(StackException)
{
if (isEmpty())
throw StackException("StackException: stack empty on pop");
else
{ // stack is not empty; retrieve and delete top
stackTop = topPtr->item;
StackNode *temp = topPtr;
topPtr = topPtr->next;
// return deleted node to system
temp->next = NULL; // safeguard
delete temp;
} // end if
} // end pop
void Stack::getTop(StackItemType& stackTop) const throw(StackException)
{
if (isEmpty())
throw StackException("StackException: stack empty on getTop");
else
// stack is not empty; retrieve top
stackTop = topPtr->item;
} // end getTop
This is the compiler error:
C:\Documents and Settings\Owner\My... In member function `int postfixcalc::eval()':
35 C:\Documents and Settings\Owner... void value not ignored as it ought to be
37 C:\Documents and Settings\Owner... void value not ignored as it ought to be
Upvotes: 1
Views: 1994
Reputation: 54979
Stack::getTop()
is declared like so:
void getTop(StackItemType& stackTop);
void
means that the function doesn’t return a value. Thus, attempting to assign the result of calling opers.getTop()
to operand2
is not possible, because getTop()
doesn’t return anything! getTop()
takes a reference parameter, so it can assign the top value directly to the variable you pass:
opers.getTop(operand2);
Instead of writing your own Stack
class, you could just use std::stack
:
#include <stack>
#include <iostream>
int main(int argc, char** argv) {
std::stack<int> stack;
stack.push(3);
std::cout << stack.top() << '\n';
stack.pop();
}
…Unless of course this is a learning exercise, in which case simply file away the tip for the future. Once you know how something is done, you should take advantage of the fact that other people have already done the work for you in a reusable way.
Upvotes: 1
Reputation: 66922
void Stack::getTop(StackItemType& stackTop) const throw(StackException)
int postfixcalc::eval()
{
int operand1, operand2, result;
operand2 = opers.getTop(op);
The getTop
function does not return anything, and then you take that nothing and store it in an int
. I think you wanted something more like this for that line:
opers.getTop(operand2);
Upvotes: 1