I'm writing a program that uses stacks to evaluate infix expressions read in from a file. Here is the code:
ptStack.h
#ifndef STACK
#define STACK
#include <cstdlib>
#include <iostream>
using namespace std;
template <class Item>
class Stack
{
public:
// CONSTRUCTOR
Stack( ) {top = NULL; count = 0;} // Inline
// MODIFIER MEMBER FUNCTIONS
void push( const Item& entry);
Item pop( );
// CONSTANT MEMBER FUNCTIONS
int size( ) {return count;} // Inline
bool is_empty( ) {return count == 0;} // Inline
private:
// DATA MEMBERS
struct Node
{
Item element;
Node *next;
};
Node *top;
int count;
};
#endif
ptStack.cpp
#include <cassert>
#include "ptStack.h"
using namespace std;
// MODIFIER MEMBER FUNCTIONS
template <class Item>
void Stack<Item>::push(const Item& entry)
{
Node *temp;
temp = new Node;
temp->element = entry;
temp->next = top->next;
top->next = temp;
count++;
}
template <class Item>
Item Stack<Item>::pop( )
{
Item value;
Node *temp;
value = top->next->element;
temp = top->next;
top->next = top->next->next;
delete temp;
count--;
return value;
}
infix.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include "ptStack.h"
using namespace std;
// PRECONDITION: op must be an operator
// POSTCONDITION: returns precedence of operator
int pr(char op)
{
int precedence = 0;
switch (op)
{
case '+':
case '-': precedence = 1;
case '*':
case '/': precedence = 2;
default : precedence = 0;
}
return precedence;
}
// PRECONDITIONS: optr is one of the following: + - * /
// opnd1 and opnd2 are numbers from 1-9
// POSTCONDITIONS: returns the result of the chosen mathematical operation
int apply(char optr, int opnd1, int opnd2)
{
int result;
switch (optr)
{
case '+': result = opnd2+opnd1;
case '-': result = opnd2-opnd1;
case '*': result = opnd2*opnd1;
default : result = opnd2/opnd1;
}
return result;
}
int main()
{
Stack<int> numbers;
Stack<char> operators;
char ch, optr;
int num, opnd1, opnd2, prec = 0, newprec;
ifstream in_file; // input file
char in_file_name[20]; // name of input file (20 letter max)
cout << "Enter input file name: ";
cin >> in_file_name;
in_file.open(in_file_name); // opens file to read equations
while (!in_file.eof())
{
cout << "Expression: ";
while(in_file >> ch)
{
if (ch == ' ')
{}
else
{
num = ch - '0';
if((num < 10) && (num > 0))
{
cout << num << " ";
numbers.push(num);
}
else if((ch == '+') || (ch == '-') || (ch == '*') || (ch == '/'))
{
cout << ch << " ";
newprec = pr(ch);
if(newprec >= prec)
{
prec = newprec;
operators.push(ch);
}
else if(newprec < prec)
{
optr = operators.pop( );
opnd1 = numbers.pop( );
opnd2 = numbers.pop( );
num = apply(optr, opnd1, opnd2);
numbers.push(num);
operators.push(ch);
}
}
}
if(in_file.peek() == '\n')
break;
}
num = operators.size();
while(num != 0)
{
optr = operators.pop( );
opnd1 = numbers.pop( );
opnd2 = numbers.pop( );
num = apply(optr, opnd1, opnd2);
numbers.push(num);
num = operators.size( );
}
num = numbers.pop( );
cout << endl << "Value = " << num << endl << endl;
}
return 0;
}
It looks like everything should work but when I compile it, I get this error message.
> g++ -c ptStack.cpp
> g++ infix.cpp ptStack.o
Undefined first referenced
symbol in file
_ZN5StackIcE4pushERKc /var/tmp//ccwhfRAZ.o
_ZN5StackIiE4pushERKi /var/tmp//ccwhfRAZ.o
_ZN5StackIcE3popEv /var/tmp//ccwhfRAZ.o
_ZN5StackIiE3popEv /var/tmp//ccwhfRAZ.o
ld: fatal: symbol referencing errors. No output written to a.out
I've been able to pinpoint the errors to the callings of the push and pop member functions in the main of the infix file. I tried defining them inline in the header file like the size function and it compiles just fine using g++ infix.cpp ptStack.h, but then I get a segmentation fault when I run it.
Does anyone know how to fix either of these errors? Thanks in advance.