Calculator Program

I have a c++ book that has given me some code for input and execution for a calculator program. I created a template class for Node and Stack operations for storage and have it working, I think... Anyways I cannot figure out why it's no adding when I am using the program, I think I am just confused on how they implemented the commands..

Stack.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef STACK_H
#define STACK_H

#include <iostream>
#include <new>
#include <cstdlib> 
using namespace std;

#include "Node.h"

template <typename T>
class Stack {
private:
    Node<T>* top;
public:

    class StackEmptyException {
    }; // empty inner typename for exception handling
    Stack();
	char get_command(); 
	bool do_command(char command, Stack<T> &numbers); 
    virtual ~Stack();
    void push(T);
    T pop();
    bool isEmpty();
    bool isFull();
};

// constructor: new stack is created. top is null.

template <typename T>
Stack<T>::Stack() {
    top = NULL;
}

// destructor: free all the memory allocated for the stack

template <typename T>
Stack<T>::~Stack() {
    while (!isEmpty())
        pop();
}

// push a data onto the stack

template <typename T>
void Stack<T>::push(T data) {
    try {
        Node<T>* newNode = new Node<T > (data);
        newNode->setNext(top);
        top = newNode;
    } catch (bad_alloc &e) {
        cout << "memory allocation exception: " << e.what() << endl;
        exit(1);
    }
}

// pop the data from the stack

template <typename T>
T Stack<T>::pop() {
    if (isEmpty())
        throw StackEmptyException();

    T data = top->getData();
    Node<T>* discard = top;
    top = top->getNext();
    delete discard;
    return data;
}

// is stack empty?

template <typename T>
bool Stack<T>::isEmpty() {
    if (top == NULL) return true;
    else return false;
}

// is stack full? 

template <typename T>
bool Stack<T>::isFull() {
    return false; // never, unless memory is full
}
template<typename T>
bool do_command(char command, Stack<T> &numbers) {
	double p,q; 
	switch(command) {
	case '?':
		cout << "Enter a real number: " <<flush;
		cin>>p; 
		if(numbers.isFull()) 
			cout << "Warning: Stck full, lost number" <<endl;
		break; 
	case '=':
		if(numbers.isEmpty())
			cout << "Stack empty" <<endl; 
		else {
			cout << p << endl; 
			break; 
		}
	case '+':
		if(numbers.isEmpty())
			cout << "Stack empty" <<endl; 
		else
		{
			numbers.pop();
			if(numbers.isEmpty()) {
				cout << "Stack has just one entry" <<endl; 
				numbers.push(p); 
			}
			else
			{
				numbers.pop();
				if(numbers.isFull()) 
					cout << "Warning: Stack full, lost result" <<endl;
			}
		}
		break; 
	case 'q':
		cout << "Calculation finished\n";
		return false;
	}
	return true; 
}
char get_command() {
	char command;
	bool waiting = true; 
	cout << "Select command and press <Enter>: ";
	while(waiting) {
		cin >> command;
		command = tolower(command);
		if(command == '?' || command == '=' || command == '+' 
			|| command == '-' || command == '*' || command == '/' 
			|| command == 'q') waiting = false; 
		else
		{
			cout << "Please enter a valid command:" <<endl
			<< "[?]push to stack [=]print top" <<endl
			<< "[+] [-] [*] [/] are arithmetic operations" <<endl 
			<< "[Q]uit." <<endl; 
		}
	}
	return command; 
}

#endif 


Node.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#ifndef NODE_H
#define NODE_H

template <class T>
class Node {
private:
  T data;
  Node<T>* next;
public:
  Node(T);
  virtual ~Node(); // base class destructor must be virtual
  T getData();
  Node<T>* getNext();
  void setNext(Node<T>*);
  void setData(T d);
};

// constructor: create a new Node with d as data
template <class T>
Node<T>::Node(T d) {
  data = d;
  next = 0;
}

template <class T>
Node<T>::~Node() {
}

// store data
template <class T>
void Node<T>::setData(T data) {
  this->data = data;
}

// set link
template <class T>
void Node<T>::setNext(Node<T>* next) {
  this->next = next;
}

// get next link
template <class T>
Node<T>* Node<T>::getNext() {
  return next;
}

template <class T>
T Node<T>::getData() {
  return data;
}

#endif 


main.cpp

1
2
3
4
5
6
7
8
#include "Stack.h"

int main() {
Stack<double> numbers; 

while(do_command(get_command(),numbers));
return 0; 
}
In case '?' you never call push.
In case '=' you only break if the stack is not empty.
I added the numbers.push(p); for '?' command, but when I run the program it gives me 0 every time when I use '=' after pushing real numbers.
In case '=' you print p which is uninitialized.
that makes sense, my next question is:

if p is the oject that they are using to store and print nodes, for '=' i would want to cout << numbers.top?
nevermind, I had to look at it a little longer, using cout<<numbers.pop() was the appropriate method
If you're not after learning classes and data structure but rather after the calculator itself, use the STL containers, stack is supported.
Topic archived. No new replies allowed.