0

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;
    }
}
  • OK, are you sure you want a stack? If each line is an expression, you can read it into a tree, lvalue op rvalue (for unary - no lvalue). Then once the tree is built in memory, you traverse it, but output BOTH values followed by the op. I've tried following the program logic and I dont' follow. – Rob11311 Feb 07 '16 at 22:57
  • This is an input problem, not a postfix problem, but you don't need both a tree and a stack. You need a tree if you're going to reprocess things, for example common subexpression elimination, but to either output postfix immediately or evaluate it immediately you only need a stack. – user207421 Feb 07 '16 at 23:03
  • I should just get something simple working, with + & -, then add in terms with multiplication/division plus parentheses later, higher precedence can be done by grouping within the tree. So 7*(5-2) + 4, has subl + 4, with subl a tree node 7 * subr, where subr is 5-2 – Rob11311 Feb 07 '16 at 23:08
  • I don't think you appreciate that converting correctly to postfix already accomplishes all that, and you don't need a tree for that process at all. – user207421 Feb 07 '16 at 23:26
  • You may want to change your `while` loop expression: `char testValue; while (inputFile >> testValue) {...}`. You should read [this post](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) as to why testing for EOF is bad. – Thomas Matthews Feb 07 '16 at 23:37
  • @EJP : no I see your point. I was looking for a clear simple to understand method that seperated the char handling from the logic and normally you do want to do more than re-arrange operator order. So the stack's intended to push ops that are lower precedence until the values/expressions they will operate on have completed. – Rob11311 Feb 07 '16 at 23:40
  • The requirements for the project are to use a stack. – Tarquiniius Feb 08 '16 at 00:36
  • @ThomasMatthews Thanks for that, makes sense. – Tarquiniius Feb 08 '16 at 00:42

0 Answers0