Why don't use GoTo?

Hey!

So I made this homework where I should programe my own calculator, in the way I wanted it. It didn't came out the way I wanted it but I had to wrapped it up because of deadline. It's like two calculators in one menu. You choose which one you want, either a calculator that refreshes after each action or another one that keeps the sum and you can continue. The problem with my code was that you couldn't switch between those two option, which the teacher pointed out. I couldn't find a way to solve it before deadline so I just used break; so the user hade to start over the program. Now I want to fix it for myself just for my own learning experience. So I google it and find Goto;. And hey, it works fine. I'm back to the beginning of my code and the user can switch calculator.

Then I read to never use Goto if you are not in deep nestled loops, but I can not find a real reason why. So why don't programmers use Goto;?

And what other option should I have used? I tried to put the whole code into a loop but it didn't work.

So here's my code. Happy to learn more. Hit me :)

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
 #include <iostream>  //

using namespace std;

int main(){

    double nr1, nr2, result;    
    char operat;      
    char choise;      
    char calcSelection;  
    bool wrongOperator;   
    char repeat;


    cout << "***'''**Welcome to calculator***'''***" << endl;
    cout << " " << endl;
    backToStart1:
    backToStart2:
    cout << "Which calculator do you want to use?" << endl;                
    cout << "[1] Calculator that refreshes after every action" << endl;
    cout << "[2] Calculator that keeps sum after every action" << endl;
    cout << "[3] Quit calculator" << endl;
    cin >> calcSelection;
    cout << " " << endl;

    if(calcSelection == '3'){
        cout << "Have a good day!" << endl;
        return 0;
    }

    while(calcSelection == '1'){
        cout << "Please enter a number you want to use: ";   
        cin >> nr1;
        cout << "Now enter an Operator from +,-,*,/ you want to use: ";
        cin >> operat;
        cout << "And the other number you want to perform the action with: ";
        cin >> nr2;
        wrongOperator = false;

        switch(operat){
            case '+':
            result = nr1+nr2;  //addition.
            break;
            case '-':
            result = nr1-nr2;  //subtraktion.
            break;
            case '*':
            result = nr1*nr2;   //multiplikation.
            break;
            case '/':
            result = nr1/nr2;    //division.
            break;
            default:
            cout << "Invalid operator" << endl;   
            wrongOperator = true;
            }

        if (!wrongOperator)
            cout << nr1 << " " << operat << " " << nr2 << " = " << result << endl;
            cout << " " << endl;
            cout << "Do you want to continue? Y/N" << endl;
            cin >> choise;
            cout << " " << endl;                                

        if(choise == 'N' || choise == 'n'){
            cout << "Thanks for using refresh Calculator!" << endl;
            cout << " " << endl;
            goto backToStart1;  // Here I used break before
        }
    }

    if(calcSelection == '2')            
        cout << "Please enter a number you want to use: ";
        cin >> nr1;

        while(true){
            cout << "Now enter an Operator from +,-,*,/ you want to use: ";
            cin >> operat;
            cout << "And the other number you want to perform the action with: ";
            cin >> nr2;
            wrongOperator = false;

        switch(operat){
            case '+':
            result = nr1+nr2;  //addition.
            break;
            case '-':
            result = nr1-nr2;  //subtraktion.
            break;
            case '*':
            result = nr1*nr2;   //multiplikation.
            break;
            case '/':
            result = nr1/nr2;    //division.
            break;
            default:
            cout << "Invalid operator" << endl;   
            wrongOperator = true;
        }

        if(!wrongOperator)
            cout << nr1 << " " << operat << " " << nr2 << " = " << result << endl;
            nr1=result;  //Keeps the results.
        cout << " " << endl;
        cout << "Do you want to continue? Y/N" << endl;
        cout << " " << endl;
        cin >> choise;
        cout << " " << endl;                                 

        if(choise == 'N' || choise == 'n'){
            cout << "Thanks for using sum Calculator!" << endl;
            cout << " " << endl;
            goto backToStart2;    //Here I Used break before I found goto
        }

        if(choise == 'Y' || choise == 'y'){
        cout << "The sum is: " << nr1 << endl; 
        }

    }
 } 
Last edited on
Look at the remark in https://docs.microsoft.com/en-us/cpp/cpp/goto-statement-cpp?view=msvc-170
That code has an error. With classes in C++ that have custom constructors and destructors that get even more "interesting".

Have you heard of functions? They let us factor code into smaller pieces. Logic of the code is way easier to express with loops and functions than with goto.
those being wordy, Ill offer the short answer:
everything you can do with goto in c++ can be done a better way with the single exception of hopping out of deeply nested loops.

because it can be done better another way, and because goto is prone to abuse, it has become unwelcome in c++ code for many decades. Nothing more -- it is legal, it works, it does what it does very well, but you would be unwise to use it in anything professional due to the stigma, even if what you wrote was clean and nice.

here is your code with the gotos replaced. I also had to add some {} around some of your if statements that didn't properly do so. It could be better; your original design sort of hinged off the gotos and fixing it made it suboptimal but doing the least changes necessary this gets you back on track:
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

int main(){

    double nr1, nr2, result;    
    char operat;      
    char choise{'x'};      
    char calcSelection;  
    bool wrongOperator;   
    char repeat;


    cout << "***'''**Welcome to calculator***'''***" << endl;
    cout << " " << endl;
    //backToStart1:
    //backToStart2:
	do
	{
    cout << "Which calculator do you want to use?" << endl;                
    cout << "[1] Calculator that refreshes after every action" << endl;
    cout << "[2] Calculator that keeps sum after every action" << endl;
    cout << "[3] Quit calculator" << endl;
    cin >> calcSelection;
    cout << " " << endl;

    if(calcSelection == '3'){
        cout << "Have a good day!" << endl;
        return 0;
    }

    while(calcSelection == '1' && choise != 'N' && choise != 'n'){
        cout << "Please enter a number you want to use: ";   
        cin >> nr1;
        cout << "Now enter an Operator from +,-,*,/ you want to use: ";
        cin >> operat;
        cout << "And the other number you want to perform the action with: ";
        cin >> nr2;
        wrongOperator = false;

        switch(operat){
            case '+':
            result = nr1+nr2;  //addition.
            break;
            case '-':
            result = nr1-nr2;  //subtraktion.
            break;
            case '*':
            result = nr1*nr2;   //multiplikation.
            break;
            case '/':
            result = nr1/nr2;    //division.
            break;
            default:
            cout << "Invalid operator" << endl;   
            wrongOperator = true;
            }

        if (!wrongOperator)
		{
            cout << nr1 << " " << operat << " " << nr2 << " = " << result << endl;
            cout << " " << endl;
            cout << "Do you want to continue? Y/N" << endl;
            cin >> choise;
            cout << " " << endl;                                
		}

        if(choise == 'N' || choise == 'n')
		{
            cout << "Thanks for using refresh Calculator!" << endl;
            cout << " " << endl;
            //goto backToStart1;  // Here I used break before
        }
    }
   
    if(calcSelection == '2')   
	{
        cout << "Please enter a number you want to use: ";
        cin >> nr1;
	}

        while(choise != 'N' && choise != 'n')
		{
            cout << "Now enter an Operator from +,-,*,/ you want to use: ";
            cin >> operat;
            cout << "And the other number you want to perform the action with: ";
            cin >> nr2;
            wrongOperator = false;

        switch(operat){
            case '+':
            result = nr1+nr2;  //addition.
            break;
            case '-':
            result = nr1-nr2;  //subtraktion.
            break;
            case '*':
            result = nr1*nr2;   //multiplikation.
            break;
            case '/':
            result = nr1/nr2;    //division.
            break;
            default:
            cout << "Invalid operator" << endl;   
            wrongOperator = true;
        }

        if(!wrongOperator)
		{
            cout << nr1 << " " << operat << " " << nr2 << " = " << result << endl;
            nr1=result;  //Keeps the results.
        cout << " " << endl;
        cout << "Do you want to continue? Y/N" << endl;
        cout << " " << endl;
        cin >> choise;
        cout << " " << endl;  
		}		

        if(choise == 'N' || choise == 'n'){
            cout << "Thanks for using sum Calculator!" << endl;
            cout << " " << endl;
            //goto backToStart2;    //Here I Used break before I found goto
        }

        if(choise == 'Y' || choise == 'y'){
        cout << "The sum is: " << nr1 << endl; 
        }

    }
	
 }while(choise == 'N' || choise == 'n');
}
Last edited on
Why not just have 1 calculator with the default value for 'Please enter a number you want to use: ' the value from the previous calculation - or 0 if no previous? If the default number is wanted, then just press <CR> otherwise enter a new number to use.
George P, Thanks.

AbstractionAnon, well... Touché. :)

Keskiverto, I have only done programming for 7 weeks, and not at full time. I've read about function but I've only used them very little. Just a celsius/fahrenheit converter that I called on. So I'm realy just at the basics. I will dig deeper into functions.

jonnin, Thanks man. I realy appreciate your answer. I'm still thinking inside the box when I'm trying to code. Like I was so caught to get the loop working but I put the whole code into one at the beginning, and I could figure out how to come back to the menu. When I see you put the while at the end I'm just feeling I want to bash my head on the computer screen, why didn't I think of that? It make so much sense.

seeplus, still learning. My idea was to have one, but I couldn't get it to work before deadline. Therefor I did the way I did. But yes, why continue with the code and not try to fix the calculator I want? First of all it is because I wanted to learn more about the loops and goto, which I have due to those many answers. Second, I will try to make it into one calculator by restart the whole code, because one calculator was my original plan. The calculator homework is already completed but for my own experience and learning I will continue on my spare time, to get it the way it was meant to be.
Last edited on
C++ is challenging, and 7 weeks part time study is next to nothing; even full time study its not much unless you are coming into it for language only (meaning you know a lot about programming, but not about this language, in which case you are just learning syntax without concepts mostly).

Programming is challenging too, so learning both at once is a lot of work.

Loops are almost never well presented to students.
so, a short extra for you:
all C loop types can be used interchangeably. Trust me on this for a moment. The range-based for loop (RBFL) is special, it represents a pointer based loop in C as a cleaner syntax using c++ iterators (pointer like things) and you can't make a while loop do that (without going back to C syntax) easily. So ignoring the RBFL for today... we have while, do-while, and for loops in C++ (also ignoring go-to). if they can all be used interchangeably, how, and how do you decide which to use?
well, its not too hard :)

the for loop is used when you want to have one or more variable activities or actions in the loop body. The for loop syntax, of course, is for(initialize, loop stop condition, action). You can be obnoxious and make the action do anything, like cout: for(int i{}; i < 10; cout<< ++i << endl); //see the ; on the end of the loop? all the fun is in the action section!
This is showing off, though, and the recommended practice for most code, just so it is easier to read, follow, work on, debug, and so on is to use the action to modify the variable(s) in the initializer part. so more typically you see for(int i{}; i < 10; i++) {actions;}.
a for loop that is a while loop looks like for(; i < 10 ;). This is kinda stupid looking, and senseless: use a while loop already!

the while loop is used when the loop body may execute 0 or more times.
it is simply while(stop condition) and stop condition can be met the first time, which would skip the loop. A while loop can play at being a for loop:
1
2
3
4
5
6
int i{}
while (i< 10)
{
  actions;
  i++;
}

here again, that is sort of goofy: use a for loop!

and the do-while is the hardest for students to grasp.
the main point is simply that you want to run the loop body at least one time, regardless of the stop condition. This nets you that idea, and it also prevents the clunky setup outside the loop stuff you can see with a while loop. a quick example of that, lets say you want to validate some input.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//the while way:
prompt for input //you can also set input invalid here instead.
cin >> input;     //but then you have odd logic if you have an invalid/try again message. 
while(input is not good)
{
  //  repeat the above lines
  prompt for input again
  cin >> input; //again...
}

//and the do while way
do
{
   prompt
   cin >> input  
     //and simply if invalid print try again message here if desired.
} while(input is no good)


all that to reiterate (ha!) ... you can use any of these 3 for anything that needs looping. So if you pick the wrong one, its not the end of the world. But as you can see, if you pick the right one, it will be easier to write, easier to read, and more elegant than just clobbering it with whatever you felt like typing that day. So thats it in a nutshell.. the right loop saves clunk and makes it nicer both to write and for the reader. If you used the wrong one once in a while (ha!), its ok. It happens to everyone!
Last edited on
I have only done programming for 7 weeks, and not at full time.

I've been self-teaching programming and C++ since before 1998 as a hobby, off and on, so 7 weeks is like nothing. :)

If you are willing to spend some time reading and trying out sample snippets of code you could spend some time at Learn C++: https://www.learncpp.com/

It's free, and kept fairly up-to-date. You won't learn ALL C++ has to offer, but you will be exposed to a large chunk of what's available.

There's also an online and free C & C++ reference site: https://en.cppreference.com/w/

The examples at cppreference are not for beginners.
Note that for a for loop, each of the 3 parts is optional. This is valid:

1
2
for (;;)
 // Body line goes here 


The for loop will execute infinite unless the body code uses break; If you look at old c code you'll likely to find this. Now to have an infinite loop with a break condition it's usual to use:

1
2
while (true)
// Body line goes here 


As this is 1 April, consider:

 
for (;;);


PS @Dantrew. Now that you know about goto, please erase all knowledge from your brain and pretend you don't know anything about it. It doesn't exist. it doesn't exist...

Last edited on
Perhaps something like:

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

int main() {
    constexpr char valid[] {"+-*/"};
    double nr1 {};
    bool exit {};

    std::cout << "***'''**Welcome to calculator***'''***\n\n";

    while (!exit) {
        std::string num;
        char operat {}, choise {};
        double nr2 {}, result {};

        std::cout << "Please enter a number you want to use [" << nr1 << "]: ";
        std::getline(std::cin, num);
        if (!num.empty())
            nr1 = std::stod(num);

        do {
            std::cout << "Now enter an Operator from +,-,*,/ you want to use: ";
            std::cin >> operat;
        } while ((std::strchr(valid, operat) == nullptr) && (std::cout << "Invalid operator\n"));

        std::cout << "And the other number you want to perform the action with: ";
        std::cin >> nr2;

        switch (operat) {
            case '+':
                result = nr1 + nr2;
                break;

            case '-':
                result = nr1 - nr2;
                break;

            case '*':
                result = nr1 * nr2;
                break;

            case '/':
                result = nr1 / nr2;
                break;
        }

        std::cout << nr1 << " " << operat << " " << nr2 << " = " << result << '\n';
        nr1 = result;

        do {
            std::cout << "\nDo you want to continue? (Y/N): ";
            std::cin >> choise;
            std::cin.ignore();

            if (choise == 'N' || choise == 'n') {
                std::cout << "Thanks for using sum Calculator!\n";
                exit = true;
                break;
            }
        } while ((choise != 'Y' && choise != 'y') && (std::cout << "Invalid option\n"));
    }
}


Note no input number checking.
Topic archived. No new replies allowed.