This program reads an input file, and from that input file changes each incoming infix line to postfix notation. Everything seems to be working except the nested while loop in my main() that deals with the operation symbols (* / + -). When it is commented out the output is a lot better. I am unsure of why it is entering an infinite loop.
I left most of the pseudo-code on main so the reader can see my line of thought, there is probably a better way to execute this program.
tests.txt contains:
4
5+7
7*5
(5-3)
5/5
8*5+3
8*(5+3)
8+3*5-7
(8+3)*(5-6)
((8+3)*(2-7))
((8+3)*2)-7
(8*5)+((3-2)-7*3)
((8*5+3)-7)-(5*3)
7*9+7-5*6+3-4
Node.h
#pragma once
template <class T>
struct Node
{
// Data members
T data;
Node<T>* next;
// Constructor
Node(T d);
};// End the Node struct
template<class T>
Node<T>::Node(T d)
{
data = d;
next = nullptr;
}
Stack.h
#pragma once
#include "Node.h"
template <class T>
class Stack
{
private:
Node<T>* head;
public:
// Constructor
Stack();
// Destructor
~Stack();
// push
void push(T);
// pop
void pop();
// top
T top();
// empty
bool empty();
};// End Stack template
template<class T>
Stack<T>::Stack()
{
head = nullptr;
}
template<class T>
Stack<T>::~Stack()
{
// While the stack is not empty
if (empty() != true)
{
// Create a temporary Node
Node<T>* temp;
// Set the temp to the next node
temp = head->next;
// Delete the first node
delete head;
// Set the first node to the next node
head = temp;
}
}
template<class T>
void Stack<T>::push(T value)
{
// Make a new node with value
Node<T>* incomingTop = new Node<T>(value);
// Set its pointer to the current top
incomingTop->next = head;
// Set the top to the new value
head = incomingTop;
}
template <class T>
void Stack<T>::pop()
{
// If the stack is not empty
if (empty() != true)
{
// Set a new pointer to the top
Node<T>* oldTop = head;
// Set the top to its next
head = head->next;
// Delete the oldTop
delete oldTop;
}
}
template <class T>
T Stack<T>::top()
{
// If the stack is not empty
if (empty() != true)
{
// Return the data in the top
return head->data;
}
}
template<class T>
bool Stack<T>::empty()
{
// If the top of the stack is null
if (head == nullptr)
{
// The stack is empty
// Return true
return true;
}
else // Otherwise
{
// The stack has data
// Return false
return false;
}
}
calc.cpp
// Include necessary files
#include "Stack.h"
#include <iostream>
#include <fstream>
#include <string>
#include <assert.h>
using namespace std;
typedef char valueType;
/* precedence function
Purpose: Determines if the passed in char is of higher precedence */
int precedence(char);
// main
int main()
{
cout << "Postfix expressions translated from ''tests.txt''";
Stack<valueType> storage;
ifstream input;
input.open("tests.txt");
if (input.fail())
{
cout << "Could not open input file." << endl;
}
// While not at the end of the file
while (input && input.peek() != EOF)
{
// Read and store a charachter from the input file
char testValue = input.get();
// If the value is a newline charachter
if (testValue == '\n')
{
// Then create a newline on the console
cout << endl;
// Empty the stack
while (storage.empty() == false)
{
// Display the top of the stack
cout << storage.top();
// Pop
storage.pop();
}
}// End if for newline charachter
// If the value is a left paren
else if (testValue == '(')
{
// Store it on the stack
storage.push(testValue);
}
// If the value is an operation symbol
else if (testValue == '+' || testValue == '-' || testValue == '*' || testValue == '/')
{
/* While:
The stack is not empty
Or the next symbol on the stack is not a left paren
Or the next symbol is not of higher precedence */
while (storage.empty() != true || storage.top() != '(' || precedence(testValue) >= precedence(storage.top()))
{
// Display the test value
cout << testValue;
// Make the test value the top of the stack
testValue = storage.top();
// Pop the top of the stack
storage.pop();
}// End nested while loop
/* If the above while loop is exited
Push test value onto the stack */
storage.push(testValue);
}// End else if for operation symbols
// If the value is a right paren
else if (testValue == ')')
{
// While the top is not a left paren
while (storage.top() != '(')
{
// If no left paren is encountered then halt the program
assert("There were unblanced parentheses. Halting the program.", storage.empty == true);
// Print the top operation
cout << storage.top();
// Pop the top value
storage.pop();
}// End nested while loop
// Pop the left paren
storage.pop();
}// End else if for the right paren
else // Otherwise if the value is an operand (number or variable)
{
// Write it out to the console
cout << testValue;
}
}// End outer while loop
input.close();
cout << endl;
system("PAUSE");
return 0;
}// End main
int precedence(char c)
{
if (c == '*' || c == '/')
{
return 2;
}
if (c == '+' || c == '-')
{
return 1;
}
else
{
return 0;
}
}