Goto

Ok so i've been working on this menu program for a while now, using various methods. I decided to give Goto a try even though people recommened not using it. However this program works well and has been the most effective method so far without any faults.

My question is, what are the alternatives to Goto? is there a more simplified (working) method for what I want to achieve?

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

using namespace std;

//selection variable
int choice;

//function prototypes
int Menu();
int Options();
int Sound();


//variable used to keep loop running
bool running = true;

int main()
{

//==========================looping selections================
while(running !=false)
{
loop: 
{Menu();}
switch(choice)
{
case 1:
loop2:
system("CLS");
Options();
		switch(choice)
		{
		case 1:
		system("CLS");
		Sound();
			switch(choice)
			{
			case 1:
			goto loop2;
			case 2:
			exit(0);
			break;
			}

	case 2:
		system("CLS");
		goto loop;
		}
break;
case 2: 
	running = false;
	break;

default:
	cout << "Incorrect selection, please choose again\n" << endl;
	cin.get();
	goto loop;
}
};
//=============================================================

cin.get();
return 0;
}


int Menu()
{

	cout << "::Main Menu::\n" << endl;
	cout << "1) options" << endl;
	cout << "2) exit program\n" << endl;

	cout << "please select an option: ";
	cin >> choice;

	return choice;

}

int Options()
{

	cout << "::Options Menu::\n" << endl;
	cout << "1) sound" << endl;
	cout << "2) go back\n" << endl;

	cout << "please select an option: ";
	cin >> choice;

	return choice;

}

int Sound()
{

	cout << "::Sound Menu::\n" << endl;
	cout << "1) This is the sound menu" << endl;
	cout << "Press 1 to go back to the options menu or 2 to exit: ";
	cin >> choice;

	return choice;

}
The command "goto" is a tool, just like everything else in C and C++. It has it's uses otherwise it would not be included in the language. The biggest problem I've seen with "goto" is that people who end up using it early on in their learning make some crazy concession in their code in order for it to work, where there are often better solutions.
Well, first things first. That indentation is unacceptable.
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
int main()
{

    //==========================looping selections================
    while(running !=false)
    {
loop: 
        Menu();
        switch (choice)
        {
            case 1:
loop2:
                system("CLS");
                Options();
                switch(choice)
                {
                    case 1:
                        system("CLS");
                        Sound();
                        switch(choice)
                        {
                            case 1:
                                goto loop2;
                            case 2:
                                exit(0);
                            break;
                        }
                    case 2:
                        system("CLS");
                        goto loop;
                }
                break;
            case 2: 
                running = false;
                break;

            default:
                cout << "Incorrect selection, please choose again\n" << endl;
                cin.get();
                goto loop;
        }
    }
    //=============================================================

    cin.get();
    return 0;
}

What you have here is a state machine. Most menu trees will need one. One way to avoid goto would be
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
state = MAIN_MENU;
while (running){
    switch (state){
        case MAIN_MENU:
            state = Options();
            break;
        case OPTION_1:
            system("CLS");
            state = Options() + SECOND_MENU;
            break;
        case OPTION_1 + SECOND_MENU:
            system("CLS");
            state = Sound() + THIRD_MENU;
            break;
        case OPTION_1 + THIRD_MENU:
            state = OPTION_1;
            break;
        case OPTION_2 + THIRD_MENU:
            exit(0);
        case OPTION_OTHER + THIRD_MENU:
            break;
        case OPTION_2 + SECOND_MENU:
            system("CLS");
            state = MAIN_MENU;
            break;
        case OPTION_2:
            running = false;
            break;
        case OPTION_OTHER:
            //In reality, this code should be part of Options(). I only put it
            //here for the sake of the example.
            cout << "Incorrect selection, please choose again\n" << endl;
            cin.get();
            state = MAIN_MENU;
            break;
    }
}
Last edited on
I would still not use goto in this application. Actually some of the goto's here are not necessary since the program execution shall automatically reach the spot you intended without the goto call.

Moreover, I would break the nested switch statements into different functions. It would improve readability and make debugging a lot easier.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
while(running !=false)
{
     Menu();
     switch(choice)
     {
       case 1:
            system("CLS");
            Options();

           // this function handles the new choice. The return value decides whether
           // the Menu is to be run again or not.
            running = handle(choice2);
            break;

       case 2: 
	running = false;
	break;

       default:
	cout << "Incorrect selection, please choose again\n" << endl;
	cin.get(); 
     }
}
Last edited on
interesting methods, thanks. I haven't seen the "state" keyword before, is there somewhere I can read up on this? (or is it just a variable)
Last edited on
It's not a keyword, it's a variable; I just forgot to declare it. You can make it of an integer or enum type.
thanks again!
closed account (iAk3T05o)
Just a note: if you place Menu() outside the program loop and call it in the loop because of some user error, it does what you want.
That's how i've avoided goto. It restarts the program from where Menu() was first called like you would do with your first goto.
i.e.
1
2
3
4
5
6
7
8
9
10
11
12
13
Menu (); //point 1

while (running)
{
switch (choice)
{
case 1:
  //blah
case 2:
  //blah
default:
  Menu(); //this restarts the program from point 1
}

:)
Last edited on
It restarts the program from where Menu() was first called
No, it doesn't.
Topic archived. No new replies allowed.