I am having trouble figuring out an RPN calculator where we have to use Linked List for this assignment. ( I had finished the assignment using the stack<double> method, but It HAS to be using linked lists.
I am having some trouble with the Error checking:
Too many operators (+ - / *)
Too many operands (doubles)
Division by zero
The program is supposed to continue to take and evaluate expressions until the user enters a zero (0) on a line by itself followed by a new line. I am also having some trouble with this. Since I put in my error checking for "too many operands", it
WILL NOT ALLOW ME TO DO A SECOND CALCULATAION , OUTPUT WILL BE "TOO MANY OPERANDS"
I can't seem to get an error check to work for "Too many operators"
I have tried several different things for the required error checking and looked at many other RPN questions on different sites, as you can see through some of the things I tried and commented out.
Any help would be greatly appreciated!
Thanks
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
struct NODE
{
float num;
NODE *next;
};
class stack
{
private:
NODE *head;
public:
stack();
void push(float);
float pop();
int nElements();
float display();
};
class RPN: public stack
{
public:
void add();
void subtract();
void multiply();
void divide();
};
stack::stack()
{
head = NULL;
}
void stack::push(float a_number)
{
NODE *temp = new NODE;
if (temp)
{
temp->num = a_number;
temp->next = head;
head = temp;
}
}
float stack::pop()
{
float number = 0;
if (!head)
{
return 0;
}
else
{
NODE *temp = head;
number = head->num;
head = temp->next;
delete temp;
}
return number;
}
int stack::nElements()
{
int counter=0;
for (NODE *node = head; node; node=node->next)
{
counter++;
}
return counter;
}
float stack::display()
{
//ERROR CHECKING TOO MANY OPERANDS??? PRINTING TOO MANY OPERANDS FOR : 100 10 50 25 / * - -2 / = , but still giving correct output && WILL NOT ALLOW ME TO DO A SECOND CALCULATAION , OUTPUT WILL BE TOO MANY OPERANDS
if(nElements() !=1)
{
cout << "Error: too many operands" << endl;
return 1;
}
/*
// if( nElements() < 2 )
{
cout << "Error: too many operators" << endl;
return 1;
}
*/
else //(nElements() > 0)
{
float temp = pop();
cout << temp << endl;
push(temp);
return temp;
}
}
void RPN::add()
{
if (nElements()>=2)
{
push(pop() + pop());
}
}
void RPN::subtract()
{
if (nElements()>=2)
{
push(0 - pop() + pop());
}
}
void RPN::multiply()
{
if (nElements()>=2)
{
push(pop() * pop());
}
}
int RPN::divide()
{
double op2;
op2 = pop();
if(op2 != 0.0)
{
push(pop() / op2);
}
else
{
cout << "Error: Division by zero.\n"; //??? Still printing output
return -1;
}
}
//Function prototype for isOperator
bool isOperator(const string& input);
//Function prototype for perforOperation
int performOperation(const string& input, RPN& calculator);
Int main(){
RPN calculator;
string input;
float num;
cout << "RPN Calculator: " << endl;
cout << "Input\n";
while(input != "0")
{
//Terminate program when 0 is entered by user
while(true)
{
// get input
cin >> input;
// check for being numeric value
if(istringstream(input) >> num)
{
//use push function
calculator.push(num);
}
// check for operator
else if(isOperator(input))
{
performOperation(input, calculator);
}
// If user enters 0 on a line followed by a new line, the program exits ????????????
else if(input == "0\n")
{
return -1;
}
}
}
}
bool isOperator(const string& input)
{
static const string operators ="-+*/";
if (input.length() == 1) // right size to be an operator.
{
return operators.find_first_of(input[0]) != string::npos;
// look in the operator string for the first (and only) character in input
}
return false;
}
int performOperation(const string& input, RPN& calculator)
{
//double firstOperand = 0;
//double secondOperand = 0;
//double result;
/*
if( calculator.size() > 2 ) //Error check gives a false error for last input ???
{
cout << "Error: too many operands" << endl;
return 1;
}
//Error chceck for too many operators ////STILL PRINT OUTPUT???
if( calculator.size() < 2 )
{
cout << "Error: too many operators" << endl;
return 1;
}
*/
switch (input[0])
{
case '+': calculator.add();
calculator.display();
break;
case '-': calculator.subtract();
calculator.display();
break;
case '*': calculator.multiply();
calculator.display();
break;
case '/': calculator.divide();
//if (firstOperand / 0)
//{
// cout << "Error: Divide by 0.\n";
//}
calculator.display();
break;
}
/*
if (secondOperand == 0)
{ // moved this test to here because it's the only place it matters.
cout << "Error: Division by 0.\n";
return -1;
}
*/
return 0;
}
This is the sample input and output
Input Output
10 15 + = 25
10 15 - = -5
2.5 3.5 + = 6 (or 6.0)
10 0 / = Error: Division by zero
10 20 * / = Error: Too many operators
12 20 30 / = Error: Too many operands
-10 -30 - = 20
100 10 50 25 / * - -2 / = -40
I got the error division by 0 check to work, It just keeps printing the output in addition to the error...How could I fix this?
int RPN::divide()
{
double op2;
op2 = pop();
if(op2 != 0.0)
{
push(pop() / op2);
}
else
{
cout << "Error: Division by zero.\n";
return -1;
}
}
The problem is that you always leave the result of the calculation on the stack. So when you do the second calculation you aren't starting with an empty stack. Simple fix is to delete this line in stack::display()
push(temp);
Probably should rename stack::display() to stack::display_and_pop() as well.
Related
I am trying to implement a Dynamic Stack in c++.
i have 3 members in class stack
1.cap is the capacity.
2.top- points to top of stack
3. arr- pointer to an integer.
in the class constrcutor I am allocating memory to stack(malloc).
later in the meminc() I am trying to realloc the memory.
I have written a function meminc() to realloc the memory but i get this invalid old size error.
It would be helpful if you let me know what is wrong in this code. I will also appreciate any advice given to me.
Thank you.
#include <iostream>
using namespace std;
#define MAXSIZE 5
class stack {
int cap;
int top;
int *arr;
public:
stack();
bool push(int x);
bool full();
bool pop();
bool empty();
bool meminc();
};
stack::stack()
{
cap = MAXSIZE;
arr = (int *)malloc(sizeof(int)*MAXSIZE);
top = -1;
}
bool stack::meminc()
{
cap = 2 * cap;
cout << cap << endl;
this->arr = (int *)realloc(arr, sizeof(int)*cap);
return(arr ? true : false);
}
bool stack::push(int x)
{
if (full())
{
bool x = meminc();
if (x)
cout << "Memory increased" << endl;
else
return false;
}
arr[top++] = x;
return true;
}
bool stack::full()
{
return(top == MAXSIZE - 1 ? true : false);
}
bool stack::pop()
{
if (empty())
return false;
else
{
top--;
return true;
}
}
bool stack::empty()
{
return(top == -1 ? true : false);
}
int main()
{
stack s;
char y = 'y';
int choice, x;
bool check;
while (y == 'y' || y == 'Y')
{
cout << " 1.push\n 2.pop\n" << endl;
cin >> choice;
switch (choice)
{
case 1: cout << "Enter data?" << endl;
cin >> x;
check = s.push(x);
cout << (check ? " push complete\n" : " push failed\n");
break;
case 2: check = s.pop();
cout << (check ? " pop complete\n" : " pop failed\n");
break;
default: cout << "ERROR";
}
}
}
To add to john's answer,
the way you're using realloc() is ... flawed.
bool stack::meminc()
{
cap = 2 * cap;
cout << cap << endl;
this->arr = (int *)realloc(arr, sizeof(int)*cap);
return(arr ? true : false);
}
If realloc() fails it will return nullptr and the only pointer (arr) to the original memory region will be gone. Also, instead of return(arr ? true : false); you should simply use return arr != nullptr;.
The righttm way to use realloc():
bool stack::meminc()
{
int *temp = (int*) realloc(arr, sizeof(*temp) * cap * 2);
if(!temp)
return false;
cap *= 2;
arr = temp;
return true;
}
Also, where is your copy-ctor, assignment operator and d-tor?
The full function is incorrect. It should be
bool stack::full()
{
return(top == cap - 1 ? true : false);
}
or more simply and with added const
bool stack::full() const
{
return top == cap - 1;
}
Also you are using the top variable incorrectly. Since top starts at -1 you should increment top before you set the value, not afterwards
arr[++top] = x;
Not a bug, but from a design perpective meminc should be a private function.
Assignment: For this assignment, you are to write a program, which will calculate the results of Reverse Polish expressions that are provided by the user.
You must handle the following situations (errors):
Too many operators (+ - / *)
Too many operands (doubles)
Division by zero
The program will take in a Polish expression that separates the operators and operands by a single space, and terminates the expression with an equals sign.
The program will continue to take and evaluate expressions until the user enters a zero (0) on a line by itself followed by a new line.
Problem 1: I am having a problem with telling the user that there are too many operators and operands. I tried to code it but I have no
idea where to begin with this.
Problem 2: I want the program to end when the user inputs 0, but it is not doing anything when I do it in my program.
#include<iostream>
#include<iomanip>
#include<string>
#include<sstream>
using namespace std;
class Node
{
double data;
Node *top;
Node *ptr;
public:
Node()
{
top = NULL;
ptr = NULL;
}
bool isEmpty()
{
return top == 0;
}
void pushValue(double val)
{
Node *next = new Node;
next->data = val;
next->ptr = top;
top = next;
}
double popVal()
{
if (isEmpty())
{
cout << "Error: Too many operators" << endl;
}
else
{
Node *next = top->ptr;
double ret = top->data;
delete top;
top = next;
return ret;
}
}
//Displays the answer of the equation
void print()
{
cout << "= " << top->data << endl;
}
};
bool isOperator(const string& input)
{
string ops[] = { "+", "-", "*", "/" };
for (int i = 0; i < 4; i++)
{
if (input == ops[i])
{
return true;
}
}
return false;
}
//This function tells the operators what to do with the values.
void performOp(const string& input, Node& stack)
{
double Val1, Val2;
int errorCheck = 0;
Val1 = stack.popVal();
Val2 = stack.popVal();
if (input == "+")
{
stack.pushValue(Val1 + Val2);
}
else if (input == "-")
{
stack.pushValue(Val1 - Val2);
}
else if (input == "*")
{
stack.pushValue(Val1 * Val2);
}
else if (input == "/" && Val2 != 0)
{
stack.pushValue(Val1 / Val2);
}
if (input == "/" && Val2 == 0)
{
cout << "Error: Division by zero" << endl;
errorCheck = 1;
}
if (errorCheck == 0)
{
stack.print();
}
}
int main()
{
cout << "Reverse Polish Notation Calculator!" << endl;
cout << "-------------------------------------------------------------------" << endl;
cout << "Enter your values followed by your operators(Enter 0 to exit)" << endl;
string input;
Node stack;
//Checks the user's input to see which function to use.
while (true)
{
cin >> input;
double num;
if (stringstream(input) >> num)
{
stack.pushValue(num);
}
else if (isOperator(input))
{
performOp(input, stack);
}
else if (input == "0")
{
return 0;
}
}
}
My assignment is to make a binary expression tree to convert postfix expressions to infix expressions in C++. I originally coded all my work in my Xcode IDE and would periodically ssh to linprog4 in terminal to make sure it works there because it has to before I turn it in. I don't understand the errors that are popping up when I compile it using g++ -o proj4.x -std=c++11 proj4_driver.cpp BET.cpp
This assignment was due 2 weeks ago and unfortunately when I was turning in the tar file with all my files, I forgot to include the .tar extension. I don't think that would affect my files but now they aren't compiling and I don't understand the errors I am getting. Could someone skim through my code and see if I am missing anything? I've looked over my code and it doesn't look like I accidentally typed something randomly somewhere.
Here is a screenshot of the errors I am getting
BET.h
#ifndef BET_H
#define BET_H
using namespace std;
class BET {
private:
struct BinaryNode {
string data;
BinaryNode * parent;
BinaryNode * childLeft;
BinaryNode * childRight;
bool visited; // to tell if node has been visited to or not
// Construct a blank copy version BinaryNode when an
// object of BET is created
BinaryNode( const char & d = char{}, BinaryNode * p = NULL,
BinaryNode * l = NULL,
BinaryNode * r = NULL, bool v = false )
: data { d },
parent { p },
childLeft { l },
childRight { r },
visited { v } {}
// Construct a blank move version of BinaryNode when an
// an object of BET is created
BinaryNode( char && d, BinaryNode * p = NULL, BinaryNode * l = NULL,
BinaryNode * r = NULL, bool v = false )
: data { std::move(d) },
parent { p },
childLeft { l },
childRight { r },
visited { v } {}
}; // end of BinaryNode struct
public:
// constructors and destructor
BET();
BET( const string postfix );
BET( const BET & rhs );
~BET();
// help copy constructor
bool buildFromPostfix( const string postfix );
// copy assignment operator
const BET & operator=( const BET & rhs );
void printInfixExpression();
void printPostfixExpression();
size_t size();
size_t leaf_nodes();
bool empty();
bool isOperand(BinaryNode * n);
private:
BinaryNode *root;
size_t leaves, nodes;
bool useP;
void printInfixExpression( BinaryNode * n );
void makeEmpty( BinaryNode* & t );
BinaryNode * clone( BinaryNode * t ) const;
void printPostfixExpression( BinaryNode * n );
size_t size( BinaryNode * t );
size_t leaf_nodes( BinaryNode * t );
}; // end of BET class
#endif
BET.cpp
#include <iostream>
#include <stack>
#include <sstream>
#include <string>
#include "BET.h"
//using namespace std;
// default zero-param constructor
BET::BET() {
root = new BinaryNode;
leaves = 0;
nodes = 0;
}
// one-param constructor, where parameter "postfix" is a
// string containing a postfix expression. The tree should
// be built based on the postfix expression. Tokens in the
// postfix expression are separated by space
BET::BET(const string postfix) {
root = new BinaryNode;
buildFromPostfix(postfix);
}
// copy constructor
BET::BET(const BET & rhs) {
leaves = rhs.leaves;
nodes = rhs.nodes;
root = rhs.root;
}
// destructor
BET::~BET() {
makeEmpty(root);
leaves = nodes = 0;
}
bool BET::buildFromPostfix(const string postfix) {
// Create stack to hold variables
stack<BinaryNode *> s;
stack<BinaryNode> bet;
char token;
string temp;
int index = 1;
bool doubleDigit = false;
int opCount = 0, digitCount = 0;
//stringstream hexToInt;
// iterator through postfix
for (int i = 0; i < postfix.size(); ++i) {
// grab token at iterations index
token = postfix[i];
if ( (token > '0' && token < '9') || (token > 62 && token < 80)) {
// check to see if token is an operand
// create a dynamic object of BinaryNode
BinaryNode *operand = new BinaryNode;
// check to see if next index of postfix is digit
// if its not, then we know its a double digit
// this while loop should only continue as long as the
// next index is between 0 and 9
temp = postfix[i];
while (postfix[i + index] >= '0' && postfix[i + index] <= '9') {
temp += postfix[i + index];
index++;
doubleDigit = true;
}
if (doubleDigit == true) {
i += index;
doubleDigit = false;
index = 1;
operand->data = temp;
} else {
operand->data = postfix[i];
}
s.push(operand);
digitCount++;
} else if (token == '+' || token == '-' || token == '*' || token == '/'){
// check to see if token is operator
BinaryNode *operand = new BinaryNode;
operand->data = postfix[i];
operand->childLeft = s.top();
s.top()->parent = operand;
s.pop();
operand->childRight = s.top();
s.top()->parent = operand;
s.pop();
s.push(operand);
opCount++;
} else {
// if neither, must be space or other character
if (token == ' ') {
} else
return false;
}
}
if (digitCount <= opCount) {
return false;
}
root = s.top();
nodes = size();
//leaves = leaf_nodes();
// THINGS TO DO:
// Make error cases with if statements to return false at some point
return true;
}
// assignment operator
const BET & BET::operator=(const BET & rhs) {
root = clone(rhs.root);
return *this;
}
// public version of printInfixExpression()
// calls the private version of the printInfixExpression fuction
// to print out the infix expression
void BET::printInfixExpression() {
printInfixExpression(root);
}
// public version of printPostfixExpression()
// calls the private version of the printPostfixExpression function
// to print out the postfix expression
void BET::printPostfixExpression() {
printPostfixExpression(root);
}
// public version of size()
// calls the private version of the size function to return
// the number of nodes in the tree
size_t BET::size() {
return size(root);
}
// public version of leaf_nodes()
// calls the private version of leaf_nodes function to return
// the number of leaf nodes in the tree
size_t BET::leaf_nodes() {
return leaf_nodes(root);
}
// public version of empty()
// return true if the tree is empty. return false otherwise
bool BET::empty() {
if (nodes == 0) {
return true;
} else
return false;
}
// checks whether node is operand or not
bool BET::isOperand(BinaryNode * n) {
if (n->data != "+" && n->data != "-" && n->data != "*" && n->data != "/") {
return true;
} else
return false;
}
// private version of printInfixExpression
// print to the standard output the corresponding infix expression
void BET::printInfixExpression(BinaryNode * n) {
//BinaryNode * temp = NULL;
if (n != NULL ) {
printInfixExpression(n->childRight);
cout << n->data << " ";
printInfixExpression(n->childLeft);
}
/*
if (n != NULL && useP == true) {
printInfixExpression(n->childRight);
if (isOperand(n->parent) && n->parent != NULL && !n->childLeft) {
cout << "(";
}
cout << n->data << " ";
if (isOperand(n->parent) && n->parent != NULL && !n->childRight) {
cout << ")";
}
printInfixExpression(n->childLeft);
}
*/
}
// private method makeEmpty()
// delete all nodes in the subtree pointed to by n.
// Called by functions such as the destructor
void BET::makeEmpty(BinaryNode * & n) {
if (n != NULL) {
makeEmpty(n->childLeft);
makeEmpty(n->childRight);
delete n;
}
}
// private method clone()
// clone all nodes in the subtree pointed by n. Called by
// functions such as the assignment operator=
BET::BinaryNode * BET::clone(BinaryNode * n) const {
if (n != NULL) {
root->childRight = clone(n->childRight);
root->childLeft = clone(n->childLeft);
root->data = n->data;
}
return root;
}
// private method printPostfixExpression()
// print to the standard output the corresponding postfix expression
void BET::printPostfixExpression(BinaryNode * n) {
if (n != NULL) {
printPostfixExpression(n->childRight);
printPostfixExpression(n->childLeft);
cout << n->data << " ";
}
}
// private version of size()
// return the number of nodes in the subtree pointed by n
size_t BET::size(BinaryNode * n) {
if (n != NULL) {
size(n->childLeft);
size(n->childRight);
nodes++;
}
return nodes;
}
// return the number of leaf nodes in the subtree pointed by n
size_t BET::leaf_nodes(BinaryNode * n) {
if (n != NULL) {
leaf_nodes(n->childLeft);
leaf_nodes(n->childRight);
if (n->childLeft == NULL && n->childRight == NULL) {
leaves += 1;
}
}
return leaves;
}
Driver.cpp
#include "BET.cpp"
//using namespace std;
int main() {
string postfix;
// get a postfix expression
cout << "Enter the first postfix expression: ";
getline(cin, postfix);
// create a binary expression tree
BET bet1(postfix);
if (!bet1.empty()) {
cout << "Infix expression: ";
bet1.printInfixExpression();
cout << "\n";
cout << "Postfix expression: ";
bet1.printPostfixExpression();
cout << "\nNumber of nodes: ";
cout << bet1.size() << endl;
cout << "Number of leaf nodes: ";
cout << bet1.leaf_nodes() << endl;
// test copy constructor
BET bet2(bet1);
cout << "Testing copy constructor: ";
//bet2.printInfixExpression();
// test assignment operator
BET bet3;
bet3 = bet1;
cout << "Testing assignment operator: ";
//bet3.printInfixExpression();
}
cout << "Enter a postfix expression (or \"quit\" to quit): ";
while (getline(cin, postfix)) {
if (postfix == "quit") {
break;
}
if (bet1.buildFromPostfix(postfix)) {
cout << "Infix expression: ";
bet1.printInfixExpression();
cout << "Postfix expression: ";
bet1.printPostfixExpression();
cout << "Number of nodes: ";
cout << bet1.size() << endl;
cout << "Number of leaf nodes: ";
cout << bet1.leaf_nodes() << endl;
}
cout << "Enter a postfix expression (or \"quit\" to quit): ";
}
return 0;
}
Driver.cpp #include "BET.cpp" should be #include "BET.h"
Or (and this is just for completeness, not recommended), leave the include of the .cpp, but then only try to compile the one .cpp (as in g++ Driver.cpp) - since driver will include BET and so all your code is there and will build.
I am trying to implement a system that would perform something like say the user enters 4 5 +. It would add the 4 and 5 (9) and push 9 into the stack.
For some reason the values in the stack are huge numbers so I believe it has something to do with a pointer or accessing a wrong field but I'm pulling my hair out trying to find the error. Any help on what I'm doing wrong?
#include "stack.h"
int main()
{
stack Test;
bool stop = false;
float runningtotal = 0;
while (stop == false)
{
char input;
cin >> input;
if (input == '+') {
int value1 = Test.top();
Test.pop();
int value2 = Test.top();
Test.pop();
cout << value1+value2 << endl;
Test.push(value1 + value2);
}
cout << Test.top();
std::getchar();
std::getchar();
}
And the implementation of stack
#include "stack.h"
stack::stack()
{
maxsize = MaxSize;
currentsize = 0;
sptr = new StackElement[maxsize];
}
stack::~stack()
{
delete [] sptr;
}
void stack::push(StackElement data)
{
if (currentsize < maxsize)
{
sptr[currentsize] = data;
currentsize++;
} else {
cout << "Stack is full ;-;";
}
}
void stack::pop()
{
if (currentsize == 0) {
cout << "Empty stack? ;-;";
return;
}
currentsize--;
}
StackElement stack::top()
{
if (currentsize == 0) {
cout << "Empty stack u ninja ;-;";
return NULL;
} else {
return (sptr[currentsize]);
}
}
void stack::push(StackElement data)
{
if (currentsize < maxsize)
{
sptr[currentsize] = data;
currentsize++; //<--- incrementing after so nothing in [currentsize] now
} else {
cout << "Stack is full ;-;";
}
}
StackElement stack::top()
{
if (currentsize == 0) {
cout << "Empty stack u ninja ;-;";
return NULL;
} else {
return (sptr[currentsize]);// should use currentsize-1
// latest filled cell
// since its pushing from top
}
}
Be sure to convert those ascii codes(49 ish) from keyboard to integer type explanations.
input - 48 should do it.
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.
Just compile all the .cpp files with g++
g++ ptStack.cpp infix.cpp