"Moving" strings and ints.

Pages: 12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main ()
{
 
goto next_step;
    
next_step:
          {
               string name;
               cin >> name;
               cout << "Hello " << name << ", nice to meet you";
               Sleep(5000);
               goto third_step;
               }
third_step:
         {
               cout << name; //Causes error because "name" undeclared.
               Sleep(3000);
               }
};

How can I fix that error, or can it be done. Also can can same be done with "int":s
Thank you.

Note: This is just example. The real code is much longer and complex.
Last edited on
Even though all these goto's does not make any sense to me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    string name;
    goto next_step;
 
    next_step:
    {
        cin >> name;
        goto third_step;
    }
    third_step:
    {
        cout << name << endl;
    }
}
Last edited on
you could also just remove the {} brackets around the code blocks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main ()
{
 
goto next_step;
    
next_step:
               string name;
               cin >> name;
               cout << "Hello " << name << ", nice to meet you";
               Sleep(5000);
               goto third_step;
third_step:
               cout << name; //Causes error because "name" undeclared.
               Sleep(3000);
};


But hey.. what maikel said: why goto?

Ciao, Imi.
Like note says real code is more complex, and in it I use goto`s because for example cases like this
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
cout << "Welcome adventurer!\n\n[N]ew game\n[L]oad game\n[Q]uit\n\nType 'H' to get help.\n\n";
    char MainMenu;
    cin >> MainMenu;
    switch (toupper (MainMenu))
    {
    case 'N':
         {
             cout << "\n\nLoading...\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
             Sleep(1000);
             goto char_gen_n;
             
             }
    case 'L':
         {
             cout << "\n\nSave-Load fuction coming soon.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
             Sleep(4000);
             return main ();
             
             }
    case 'Q':
         {
             cout << "\n\nThank you for playing.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
             Sleep(4000);
             return 0;
             
             }
    case 'H'://Help.
         {
             cout << "\n\nType the letter in [X], to choose the option.\nFor example 'X' in the example.\nThat will work every time ther is letter in [].\n\nTry to get back to main menu.\n\n[B]ack\n\n";
         back_training://Back training.
         {
             char backq;
             cin >> backq;
             switch (toupper (backq))
             {
             case 'B':
                  {
                      cout << "\nGood job!\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
                      Sleep(4000);
                      return main ();
                      
                      }
             default:
                  {
                      cout << "\nTry again!(By typing 'B')\n\n";
                      goto back_training;
                      
                      }
                    }
                  }
                }
    default:
          {
              return main ();
              
              }


But anyway thank you.
Last edited on
just make sure, that the input variable will be in your scope. If something is in brackets and you enter a block it will be put in the stack and will be removed if you leave the block again, and you cant access it anymore.

Maikel
Hmm... I noticed that, but how can I make it so that in case of default. It returns to the start, without using brackets.(Like for example in the "back_training" in the previous example.)
Here is another example:
1
2
3
4
5
6
7
8
char_gen_n://Character Creation_Name
             {
                        cout << "\nPlease type your name here:\n";
                        string username;
                        cin >> username;
                        cout << "\n\nYour name is " << username << ".\n\n";
                        goto char_gen_g;
                        }


Moves trough "char_gen_g" and many others and comes to this.
1
2
3
4
5
6
start_ship://Beginning of the game.
               {
                        cout << username << ", has been travelling for several days, with a ship.\n";
                        Sleep(5000);
                         
                        }//Ship end 


Now it recognize "username" but it does`t remember it`s value.
How to fix this , or any other way to do same things.
Last edited on
Just put the whole case-block of H in a loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
case 'H'://Help.
{
	cout << ...;
	while (true)
	{
		char backq;
		cin >> backq;
		switch (toupper (backq))
		{
		case 'B':
			cout << "\nGood job!\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
			Sleep(4000);
			return main();
		default:
			cout << "\nTry again!(By typing 'B')\n\n";
		}
	}
}


Since you have a "return main()" in your B-case, this is enough of a breaking condition for the loop.

Ciao, Imi
Last edited on
Do you really need to do all this with goto's ? (Some kind of excercise? Other circumstances?)

If not, I recommend wikipedia and links on this page: http://en.wikipedia.org/wiki/Goto

If you want to, you could send me your source code and i would restructure the program flow in a more modern way. Goto is nowadays regarded as more or less harmfull. So you would see, how to handle things without the use of gotos.


Maikel


Edit:

I don't want to say, gotos are always evil. Here is a good point of view:
Wikipedia wrote:

Linux Kernel designer and coder Linus Torvalds also objects to Dijkstra's point of view, stating that GOTOs can be a useful language feature, improving program speed, size and code clearness at the same time, but only when used in a sensible way by comparably sensible programmer
Last edited on
goto = evil
Recursing on main() = evil

Instead of gotos, use actual loops (while, for, etc). Instead of recursing on main, use a while loop.
I don't like absolute one-way statements like this and that is evil.
Oh! I like this very much then. :-]

Maikel
Yea but how would you make for example loop on that new game:
1
2
3
4
5
6
7
8
9
10
11
12
cout << "Welcome adventurer!\n\n[N]ew game\n[L]oad game\n[Q]uit\n\nType 'H' to get help.\n\n";
    char MainMenu;
    cin >> MainMenu;
    switch (toupper (MainMenu))
    {
    case 'N':
         {
             cout << "\n\nLoading...\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
             Sleep(1000);
             goto char_gen_n;
             
             }


And make it with this:
1
2
3
4
5
6
7
8
char_gen_n://Character Creation_Name
             {
                        cout << "\nPlease type your name here:\n";
                        string username;
                        cin >> username;
                        cout << "\n\nYour name is " << username << ".\n\n";
                        goto char_gen_g;
                        }
Last edited on
IIRC, the part with the recursion on main is not only evil, but pure sinister. (As in "it is not defined what will happen. It's not even legal C++"). Am I right?

Ciao, Imi.
Yea but how would you make for example loop on that new game
You need to construct additional functions.
Why this doesn`t work:
1
2
3
4
5
6
case 'N':
         {
             cout << "\n\nLoading...\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
             newgame = true;
             Sleep(1000);
}

+
1
2
3
4
5
6
7
8
do
{
cout << "\nPlease type your name here:\n";
string username;
cin >> username;
cout << "\n\nYour name is " << username << ".\n\n";
}
while (newgame=true);

Note "boolean newgame" made in beginning.
Last edited on
For example, you could use functions, so you would jump into other blocks too, but it would be more organized.

You could even do a mapping like this: (i would like functors more, meaing a class called Function and then doing a map<KeyType, Function>

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

void function1()
{
    cout << "Function1\n";
}

void function2()
{
    cout << "Function2\n";
}

int main()
{
    map<char,void(*)()> function_map;
    function_map.insert(pair<char,void(*)()>('1', function1));
    function_map.insert(pair<char,void(*)()>('2', function2));

    char input = cin.get();
    while (input != 'q') {
        if (function_map.find(input) != function_map.end())
            function_map[input]();
        else
            cout << "\"" << input << "\" not found!\n";

        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        input = cin.get();
    }
}
1
Function1
2
Function2
3
"3" not found!
q


Maikel
Last edited on
Thank you!
I have although one question, at the moment.
'q' is automatically resulting program to close. Question is how to make 'Q' to react same way?
Also how to continue ie:
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
void newgame()
{
    cout << "\nPlease type your name here:\n";
                        string username;
                        cin >> username;
                        cout << "\n\nYour name is " << username << ".\n\n";
                        
}

void loadgame()
{
    cout << "Load function coming soon!\n";
}

void help()
{
    cout << "Simply type the letter in [X].\nFor example in this case 'X'.\nTry to get back to main menu.\n\n[B]ack\n\n";
    
}

void empty ()
{
    cout << "Welcome adventurer!\n\n[N]ew game\n[L]oad game\n[Q]uit\n\nType 'H' to get help.\n\n";
}

int main()
{
    map<char,void(*)()> function_map;
    function_map.insert(pair<char,void(*)()>('N', newgame));//new
    function_map.insert(pair<char,void(*)()>('n', newgame));
    function_map.insert(pair<char,void(*)()>('L', loadgame));//Load
    function_map.insert(pair<char,void(*)()>('l', loadgame));
    function_map.insert(pair<char,void(*)()>('H', help));//help
    function_map.insert(pair<char,void(*)()>('h', help));
    function_map.insert(pair<char,void(*)()>('B', empty));//Back
    function_map.insert(pair<char,void(*)()>('b', empty));
    cout << "Welcome adventurer!\n\n[N]ew game\n[L]oad game\n[Q]uit\n\nType 'H' to get help.\n\n";
    char input = cin.get();
    while (input != 'q') {
        if (function_map.find(input) != function_map.end())
            function_map[input]();
        else
            cout << "\"" << input << "\" not found!\n";

        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        input = cin.get();
        
        
    }
    
};//End program 

So how to continue from "newgame"?
Last edited on
 
while (input != 'q' || input!='Q')
I designed 'q' to be some kind of quiting facility. If you want to map any other character, add:
 
    function_map.insert(pair<char,void(*)()>('Q', another_function))


If you want 'q' and 'Q' to quit just do:
1
2
3
4
5
    while (input != 'q' && input != 'Q') {
    ...
    }
    // here do more stuff
    cout << "Leaving your Game. Doing some cleaning stuff here.\n";


Maikel
Pages: 12