Advancing my calculator

Ok, I'm a newbie teaching myself from this website and a book I bought. I created a calculator with basic math operations. However, I would like to advance it to where it can work with parenthesis, powers, ect. Here is the code I have so far, how would I advance it to perform these functions.


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
#include <iostream>
#include <string>
using namespace std;

int inputx;
char operate;
int inputy;

int main() {
	
	cout << "Please enter the equation to be calculated:" << endl;
	cout << "Add = +" << endl << "Subtract = -" << endl << "Multiply = *" << endl << "Divide = /" << endl;
	
	cout << "Enter the first integer:";
	cin >> inputx;
	cout << "Enter the operator:";
	cin >> operate;
	cout << "Enter the last integer and press enter:";
	cin >> inputy;
	
	//Plus sign
	if(operate == 43)
	{
	int result = inputx + inputy;
	
	cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;	}
	//Minus Sign
	if(operate == 45){
		int result;
		result = inputx - inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
	if(operate == 42){
		int result;
		result = inputx * inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
	if(operate == 47){
		int result;
		result = inputx / inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
		string choice;
		cout << "Do you want to do another calculation?" << endl << "Yes/No" << endl;
		cin >> choice;
		if(choice == "Yes", "yes", "y"){
			return main();
	}
		else{
			return (0);
			}
		}


Thanks,
Derek
If you want to handle parenthesis then you'll probably want to write a program using something like Dijkstra's Shunting Yard Algorithm (you'll be able to find the details of that on google)

Although before you do that, there's a few other things you might want to think about..

1
2
3
4
5
6
7
#include <iostream>
#include <string>
using namespace std;

int inputx;
char operate;
int inputy; 
Here you've declared 3 variables at the top of your program - this makes your variables visible to every part of your program, so I'd suggest you get out of the habit of doing this as quickly as possible, because it will come back to bite you as soon as you start writing more complicated programs.

Variables declared here are known as Global Variables - hopefully there should be something in your book which explains in more details why these are a bad thing (otherwise try typing "Why are global variables bad?" into google..)

(And on a related note - if you're learning using a tutorial which encourages declaring variables "globally", then take it as a warning sign that whoever wrote it probably doesn't know what they're doing. Sadly that's quite common with internet tutorials)

1
2
3
4
5
		string choice;
		cout << "Do you want to do another calculation?" << endl << "Yes/No" << endl;
		cin >> choice;
		if(choice == "Yes", "yes", "y"){
			return main();
Here you've called main - this is technically illegal since main is a special function. If your compiler was being strict, then it shouldn't compile (C++ doesn't allow it), although in practise a lot of compilers use 'relaxed' rules by default and might let you get away with it, but it's a really bad idea (depending on your O/S and compiler it could crash your program or do other unusual things) - if you want to repeat blocks of code, there are much better ways.

What you want is a for or while loop - have a look in your book for the chapter which explains looping/repetition - you will need to understand repetition if you want to write any kinds of more sophisticated programs.



Finally...
1
2
	//Plus sign
	if(operate == 43) 
there's nothing technically wrong with this code, although wherever you can, you should write it in a way that doesn't need comments. It would usually be better to avoid the "magic numbers". Characters are numbers, so you could do this instead, then you won't really need a comment saying 'plus sign' - since it should be obvious from the code. - if(operate == '+' )
Last edited on
Thank you for the detailed reply!
So are you saying that I should call the variables within the function that they are being used in?
Just out of curiosity, why should you not call main()?

Everything else helped, thanks!
Alright, I added a do-while statement to the code to control if the program will restart or not... but whenever I input something, it restarts, disregarding if it was "yes" or "no"

Do you see anything wrong with the code?


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

#include <iostream>
#include <string>
using namespace std;



int main() {
	
	//Variables
	string choice;
	int inputx;
	char operate;
	int inputy;
	
	//****************************************************
	
	do {
	//Initial instructions
	cout << "Please enter the equation to be calculated:" << endl;
	cout << "Add = +" << endl << "Subtract = -" << endl << "Multiply = *" << endl << "Divide = /" << endl;
	
	cout << "Enter the first integer:";
	cin >> inputx;
	cout << "Enter the operator:";
	cin >> operate;
	cout << "Enter the last integer and press enter:";
	cin >> inputy;
	
	//Plus sign
	if(operate == '+')
	{
	int result = inputx + inputy;
	
	cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;	}
	
	//Minus Sign
	if(operate == '-'){
		int result;
		result = inputx - inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
	
	//Multiply
	if(operate == '*'){
		int result;
		result = inputx * inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
	
	//Divide
	if(operate == '/'){
		int result;
		result = inputx / inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
	//Restart?
		cout << "Do you want to do another calculation?" << endl << "Yes/No" << endl;
		cin >> choice;
	}	while (choice != "Yes" || choice != "yes" || choice != "y");
			
			return 0;
}
dkdude wrote:
Alright, I added a do-while statement to the code to control if the program will restart or not... but whenever I input something, it restarts, disregarding if it was "yes" or "no"

Do you see anything wrong with the code?

There's one minor flaw in your logic here
while (choice != "Yes" || choice != "yes" || choice != "y");
Your code will repeat if choice is not equal to "Yes", or it is not equal to "yes", or it is not equal to "y"

So, if choice == "Yes" then that means both choice != "yes" and choice != "y" are true.
If you used 'AND', you might get the result you're expecting.



dkdude wrote:
So are you saying that I should call the variables within the function that they are being used in?

A good place to put them is next to the code where they're used. if you use a variable in main, then somewhere in main is a good place. If you only use it inside an 'if' or 'while' block, then inside that block is a better place. Keeping variables down to as narrow scope as possible will better help you manage your code, and avoid the situation where you could end up with loads of variables all potentially being changed from hundreds of different areas in your program. (In big projects this can cause major headaches when there are a million+ lines of code which all have access to the same variable). If more than 1 function needs visibility of a variable, then you can write function arguments to pass them around - this gives your program a much better structure and flow.



dkdude wrote:
Just out of curiosity, why should you not call main()?

As for avoiding a recursive call of main(), there are several reasons:
1) The C++ standard forbids it (the C++ standard is a document which defines the C++ language, including what C++ programmers are allowed to do and what C++ compilers can and can't accept). Most compilers diverge away from the standard a little bit in places (And there are many things left completely open/undefined), but as a general rule of thumb you should avoid writing code which the standard says is disallowed, unless you have a compelling reason to do so.

2) main is a special function, and your compiler is allowed to do things with it which might not normally happen with other functions (Your program needs an entry point, and the compiler is allowed to do anything it needs to do in order to get it to work). There's a chance that it might behave differently when compared with a normal function, depending on the compiler.

3) Recursion eats up space on your call stack (which is generally limited - more noticably on smaller devices). Calling a function from within itself does not just "jump" to an earlier point in your code, it adds a function call frame to your stack as well - If you keep going, you'll eventually run out of stack space. If you do this with main, then each time you call main, you are effectively starting your program afresh on top of everything which your program did before (Think of it like repeatedly putting up extra layers of wallpaper without taking down the old layers first)

4) On a more general note about recursion - it can be a bit of a tough one to debug and maintain - your code will usually be simpler when you stick to the standard for/while loops. If you use recursion to repeat large chunks of your program, or to jump back-and-forth repeatedly between different functions then you may end up with a complicated web of "spaghetti" code. Recursion is occasionally very useful for particular algorithms, but it needs to be used judiciously in places where for/while aren't up to the job.
Last edited on
Here is the final code that works like I would like it too until I can advance it. Thank you very much Bench82

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

#include <iostream>
#include <string>
#include <istream>
#include <fstream>
using namespace std;



int main() {
	
	//Variables
	string choice;
	int inputx;
	char operate;
	int inputy;
	
	//****************************************************
	
	do {
	//Initial instructions
	cout << "Please enter the equation to be calculated:" << endl;
	cout << "Add = +" << endl << "Subtract = -" << endl << "Multiply = *" << endl << "Divide = /" << endl;
	
	cout << "Enter the first integer:";
	cin >> inputx;
	cout << "Enter the operator:";
	cin >> operate;
	cout << "Enter the last integer and press enter:";
	cin >> inputy;
	
	//Plus sign
	if(operate == '+')
	{
	int result = inputx + inputy;
	
	cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;	}
	
	//Minus Sign
	if(operate == '-'){
		int result;
		result = inputx - inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
	
	//Multiply
	if(operate == '*'){
		int result;
		result = inputx * inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
	
	//Divide
	if(operate == '/'){
		int result;
		result = inputx / inputy;
		
		cout << inputx<<" "<<operate<<" "<<inputy<<" ="<< " " <<result<<endl;
	}
	//Restart?
		cout << "Do you want to do another calculation?" << endl << "Yes/No" << endl;
		cin >> choice;
	}	while (choice == "Yes" || choice == "yes" || choice == "y");
			return 0;
}
Your program works, which is good. But now you should start thinking of ways to make it more user friendly. For instance, consider the following:

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
#include<iostream>
#include<string>
#include<cstdlib>

using namespace std;

int main()
{
    int i,j,k=0;
    string equation,inputx,inputy;
    double a,b;
    cout<<"Enter an equation: ";
    getline(cin, equation); /*Like cin, except that the newline
    character, and not the whitespace character, is the terminating character.*/

    //search every element of the string:
    for(i=0;i<equation.size();i++)
    {
        if(equation[i]=='+')
        {
           //assign every element of the string before the operator to inputx:
           for(j=0;j<i;j++)
           {
               if(isdigit(equation[j])||equation[j]=='.') //If the element is a digit or decimal.
               {
                   inputx[k]=equation[j];
                   k++; //Add 1 to k.
               }
           }
           k=0;
           //assign every element of the string after the operator to inputy:
           for(j=i+1;j<equation.size();j++)
           {
               if(isdigit(equation[j])||equation[j]=='.')
               {
                   inputy[k]=equation[j];
                   k++;
               }
           }
           a=atof(inputx.c_str()); //converts the string to a double.
           b=atof(inputy.c_str());
           cout<<"="<<a+b<<endl;
        }
    }
    system("pause"); //try not to use system("pause"). I'm only using it here for simplicity.
    return 0;
}


You could do this for each operator. Now the user only has to type one line. Also, the program won't crash if you enter, for instance, a letter where a number is expected (instead the program just ignores it). Of course, it could still use some work but I didn't want to make it too convoluted.
Last edited on
Wow, thanks for the reply! I really appreciate this new method, I was wanting to do this eventually.
Topic archived. No new replies allowed.