Hints on reverse polish calculator program. Headed in right direction but stuck with a few questions

I've been working for the past week on and off on this program. Its not due until the 29th but I thought it would be a good idea to get a head start on it. The basic prompt is the user enters an input to be used for a reverse polish notation using stacks.

ex: 5 6 + 3 *

I think im close to figuring it out. Ive got the basic concept, theres just a few fundamentals im sure im missing. I've tried using my book but unfortunatley it uses classes with stacks which we have not learned yet (my professor jumps around the chapters in the book). I have some code here but I think im doing a couple things wrong.

1. My struct and functions are included in the same file. I was talking with a friend in the class and he said to include everything in one file. Previously I was using three files: main.cpp stack.cpp and stack.h When using it this way I got alot less errors on compilation so I may go back to that.

2. I cant seem to figure out how to have the user input the operands. Our professor told us the easiest way was to have them enter is as a string and then
if it was a number, convert it to c_string and push it to the stack. However, I cant find a way to test the characters in the string one by one to see if they are integers or not. My code below trys to do this.

Anyways, sorry for the wall of text. If anyone could help me out that would be great, its no rush since I can ask my professor about it in class tuesday and go to CS tutoring on monday. Just thought I'd get a head start.

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
149
150
151
152
153
154
155
156
157
158
159
160
161
 //Brady Kedge
//CS2250
//Reverse Polish Project

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>

using namespace std;

//Prototypes

struct node 
{
	int data;

	node *next;
};

void showstack(node *stack);

void push(int val, node *&stack);

int pop(node *&stack);


//Variables

int value = 20;

int s1, s2, s3, s4;

int num;

string exit_prog = "e";

string user_input;




int main()
{

cout << "Enter an input \n";

cin >> user_input;	
	
	while(cin >> user_input)

	{
		for(int i = 0; i < user_input.length(); i++)
		{

			if(isdigit(user_input[i]))         //If its a number, push
			{
				user_input.c_str();

				num = atoi(user_input[i]);

				push(num, *&stack);
			}

			else if(user_input[i] == "+")     //if it is this character add by popping s1 and s2
			{
				s1 = pop(node *&stack);

				s2 = pop(node *&stack);

				push((s1 + s2), *&stack);
			}

			else if(user_input[i] == "-")  //subtracts
			{
				s1 = pop(node *&stack);

				s2 = pop(node *&stack);

				push((s1 - s2), *&stack);
			}

			else if(user_input[i] == "*")  //multiplys
			{
				s1 = pop(node *&stack);

				s2 = pop(node *&stack);

				push(((s1) * (s2)), *&stack);
			}

			else if(user_input[i] == "/")  //divides
			{
				s1 = pop(node *&stack);

				s2 = pop(node *&stack);

				push((s1 / s2), *&stack);
			}

			else if(user_input[i] == "u")  //negates
			{
				s1 = pop(node *&stack);

				s1 = s1 * -1;

				push(s1, *&stack);


			}

			else if(user_input[i] == "p")  //Outputs
			{
			
				s1 = pop(node *&stack);

				cout << s1 << endl;


			}

		}

	}

return 0;

}


//Functions

void show_stack (node *stack)
{
        cout << "TOP> ";
        for ( ; stack != NULL; stack = stack->next) {
                cout << stack->data << ' ';
                }
        cout << endl;
}

void push (int val, node *&stack)
{
        node *p = new node;
        p->data = val;
        p->next = stack;
        stack = p;
}

int pop (node *&stack)
{
        node *t = stack;
        int val = stack->data;
        stack = stack->next;
        delete t;
        return val;
}

bump?
double bump.
I'm assuming that the input will have each element separated by whitespace,
such as "5 6 + 3 * p" or "355000 113 / p". If that is the case, then you don't necessarily have to do a lot of low-level validation of numbers.

Something like this should work (well, I started testing this, but there may be a few bugs to be ironed out).

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
int main()
{
    node * stack = new node;
    string user_input;

    cout << "Enter an input \n";

    int s1;
    int s2;

    while (cin >> user_input)
    {
        if (isdigit(user_input[0]) || user_input.size() > 1)
        {
            int num;
            string dummy;
            istringstream numss(user_input);
            if ((numss >> num) && !(numss >> dummy))
            {
                push(num, stack);
            }
        }

        else if (user_input == "+")    // Add
        {
            s1 = pop(stack);
            s2 = pop(stack);
            push(s1 + s2, stack);
        }

      Etc. etc. ...


At line 13, the assumption is made that if either the first character is numeric, or the string contains more than one character, it must be a number. (I've not handled the case where there is invalid input).

Line 17, make a stringstream from the input. Attempt to extract first an integer (should succeed) followed by any other characters (should fail). If that works, push the number onto the stack.

Other comments. I've used local rather than global variables. It's generally a good idea to restrict the scope of variables to just the place where they are used.


wh33lybrdy wrote:
Previously I was using three files: main.cpp stack.cpp and stack.h
Yes, that sounds a reasonable idea. But if the other files are very small, there may not be any real motive for doing so.


Last edited on
You were correct in assuming that the string will be entered with whitespace. I tried out your method and it looks like its working alot better. Our professor told us the easiest way would be to read a string then if its a number, convert it to C-String and then convert it to an integer using atoi and to go from there but I seemed to be messing up my C-strings.

As of now I only get 1 compilation error. It says that node has already been declared in stack.h (I went back to three files, it seems easier and less jumbled that way). Im probably messing up my pointers somewhere but I dont know if you wanted to take a look at it now. Virtual tutoring opens for my school in about half an hour so I'll ask the tutor if need be. Thanks for the help!

(Here is my code)

main.cpp

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
#include "stack.cpp"
#include "stack.h"
#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>

using namespace std;

//Prototypes


int main()
{

node *stack = new node;

int value = 20;

int s1, s2;

int num;

string exit_prog = "e";

string user_input;

cout << "Enter an input \n";

cin >> user_input;


	
	while(cin >> user_input)
	{
			if(isdigit(user_input[0] || user_input.size() > 1))         //If its a number, push
			{
				string dumb;

				istringstream numss(user_input);

				if((numss >> num) && !(numss >> dumb))
				{
					push(num, stack);
				}
			}

			else if(user_input == "+")     //if it is this character add by popping s1 and s2
			{
				s1 = pop(stack);

				s2 = pop(stack);

				push((s1 + s2), stack);
			}

			else if(user_input == "-")  //subtracts
			{
				s1 = pop(stack);

				s2 = pop(stack);

				push((s1 - s2), stack);
			}

			else if(user_input == "*")  //multiplys
			{
				s1 = pop(stack);

				s2 = pop(stack);

				push(((s1) * (s2)), stack);
			}

			else if(user_input == "/")  //divides
			{
				s1 = pop(stack);

				s2 = pop(stack);

				push((s1 / s2), stack);
			}

			else if(user_input == "u")  //negates
			{
				s1 = pop(stack);

				s1 = (s1) / (-1);

				push(s1, stack);


			}

			else if(user_input == "p")  //Outputs
			{
			
				s1 = pop(stack);

				cout << s1 << endl;


			}

		

	}

return 0;

}




stack.cpp


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
#include <iostream>
#include "stack.h"

using namespace std;

void show_stack (node *stack)
{
        cout << "TOP> ";
        for ( ; stack != NULL; stack = stack->next) {
                cout << stack->data << ' ';
                }
        cout << endl;
}

void push (int val, node *&stack)
{
        node *p = new node;
        p->data = val;
        p->next = stack;
        stack = p;
}

int pop (node *&stack)
{
        node *t = stack;
        int val = stack->data;
        stack = stack->next;
        delete t;
        return val;
}




stack.h



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct node
{
	int val;

	node *next;
};



void showstack(node *stack);

void push(int val, node *&stack);

int pop(node *&stack);


You need header guards, to prevent the header from being included twice.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef Stack_H
#define Stack_H

struct node
{
	int val;
	node *next;
};

void showstack(node *stack);
void push(int val, node *&stack);
int pop(node *&stack);

#endif 


But also, you shouldn't really #include the stack.cpp file. Instead, add it to the files which are to be compiled as part of your project.

Also, when you did a copy+paste of the code I previously posted, some errors mysteriously crept in.
Mine:
 
if (isdigit(user_input[0]) || user_input.size() > 1)

yours:
 
if(isdigit(user_input[0] || user_input.size() > 1))

Notice how the parentheses moved around?

You also inserted an extra cin >> user_input; at line 33 which isn't needed, as the contents will get ignored. Delete that line.

edit One more comment
When negating the value, instead of dividing by -1 (huh ?) you could just do this:
1
2
    s1 = pop(stack);
    push(-s1, stack);
Last edited on
Topic archived. No new replies allowed.