A switch repeating itself to default in a loop

So basically, i'm writing a small game in c++. What you see is the skill point distribution function.
This is just a small solution I created to try and isolate the error, and i've been able to figure out so far that there is a problem with calling the answer for switch along with calling another user input function within the switch.
Basically the loop will have run three times by the end of the program when it is supposed to have only run twice.
This is what is happening:
1. loop runs
2. switch (user is asked for a char)
3. case chosen 's'
4. user is asked for a number
5. add points and restart loop
6. skip switch answer and go straight to default:
7. restart loop
8. switch waits for input. (three loops, where only two should have run)

Obviously I have excluded other cases, and an exit/return.

Hope you guys can help!
IDE: Visual C++ 2008 Express
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
#include <iostream>
#include <string>
#include <windows.h>
#include <istream>
#include <sstream>

using namespace std;

char GetSingleChar();
int GetNum();

int main ()
{
	bool validInput(0), stop(0);
	int points[3] = {0, 0, 0}, sPts, p;
	sPts = 5; // skill points for player to use
	for(int x=0;x>3;x++){points[x]=0;} //need to use this to reset variables when it was inside the rest of the game. Otherwise in this case it's pretty pointless.
	do
	{
		cout << "\nYou have " << sPts << " points left. Which attribute would you like to add points to?\n\n";
		cout <<"s - Strength (" << points[0] << ")";
		cout << "\nChoice: ";
		switch(GetSingleChar()) // ask user for answer
		{
			case 's':
				if(sPts>0) // make sure user still has skill points left
				{
					do // loop to make sure user enters a correct number
					{
						cout << "blah blah strength points left is " << sPts << "\n\nStrength: ";
						p = GetNum(); 
						// excluding this and makeing something like p = 1; gets rid of my problem entirely. I have even tried not using this function and doing a simple cin >> p; but that also screws it up.

						points[0] += p;
						validInput = 1;
						if (points[0] <= sPts && points[0] >= 0)
						{
							sPts -= points[0];
							validInput = 1;
						}
						else {cout << "Can't use that many points!";}
					}while(!validInput);
					validInput = 0;
				}
				else {cout << "Sorry, you have no more points left to spend.";}
				system("cls");
				stop=0;
			break;
			default:
				cout << "activated default!";
				Sleep(5000);
				stop=0;
		}
	}while(!stop);
return 0;
}

char GetSingleChar()
{
	string user_input="\0";
	char newChar='\0';
	getline(cin, user_input);
	newChar += user_input[0];
	return newChar;
}

int GetNum()
{
	int result(0);
	string text;
	istringstream iss;
	do
	{
		cin >> text;
		iss.clear();
		iss.str(text);

		if(!(iss >> result))
		{
			cerr << text <<" is not a number\n\nChoice: ";
		}

	} while(!iss);
	return result;
}
Last edited on
Your flag exit isn't working properly, you never set it to true.
The answer is that because c++ doesn't have named break, you should use a goto:
1
2
3
4
5
6
7
8
9
//this is simplified, but demonstrates the usage.
while(1){
	switch(input()){
	case 's':break;
	default:goto exit;
	}	
}
exit:
//whatever comes next 

This is the only circumstance in which I recommend gotos.
Last edited on
Yeah sorry, there is an excluded case from this solution which lets you exit the program. The reason I set it to false when user alters 'strength' is because I want them to be able to add more points to it or other attributes (which have also been excluded since they're the same piece of code, just altering different variables in the player class).
Otherwise, they would have had to alter strength, exit the nested function, enter the function again, add points into other attributes if they hadn't already spent all their skill points.

Here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
case 'q':
	cout	<< "Thats all your points spent.\nThese are your new stats:\n"
			<< "\n Strength: " << points[0]
			<< "\n\nAre you happy with this choice?\ny - I want these stats\nn - I want to choose these stats again\n\nAnswer: ";
	switch(GetSingleChar());
	{
	case 'y';
		stop=1;
		//player.setSpts(sPts);//originally program gets points to spend from the player class. for now just set sPts to 5
		//player.setStr(player.getStr()+points[0]);//sets the class player's strength variable (int)
		validInput=1;
	break;
	case 'n'://reset variables and start again.
		for(int x=0;x>3;x++){points[x]=0;}//reset points
		//sPts = player.getSpts();//get skill points from player class
		sPts = 5;
		validInput=1;
	break;
	default:
		cout << "Default - Not a valid answer";
	}
break;


EDIT: Currently I am trying to re-write the code in a different way, while also reducing lines of code. I'll make a new post with it if it works, otherwise I'll ditch it and try again.
Last edited on
Okay well, I don't know if any of you have solved the problem, but I have. Basically what was wrong, is that the fuinction GetSingleChar() would not check if I had input something in there yet, so all I had to do was keep it on a loop and if statement until user enters something.

Heres the new code, including a complete re-write of the entire function because I'm nice and like to share.
(Reduced lines of code by 30-40 something when I implemented it back into my game solution)

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
#include <iostream>
#include <string>
#include <windows.h>
#include <istream>
#include <sstream>

using namespace std;

char GetSingleChar();
int GetNum();

int main ()
{
	bool validInput(0), stop(0);
	int points[3] = {0, 0, 0}, sPts, p, x;
	sPts = 5; // skill points for player to use
	char chr;
	for(int x=0;x>3;x++){points[x]=0;} //need to use this to reset variables when it was inside the rest of the game. Otherwise in this case it's pretty pointless.
	do
	{
		cout << "\nYou have " << sPts << " points left. Which attribute would you like to add points to?\n\n";
		cout <<"s - Strength (" << points[0] << ")" <<"\ni - Intelligence (" << points[1] << ")" <<"\na - Agility (" << points[2] << ")" ;
		cout << "\nChoice: ";
		if(sPts>0){chr = GetSingleChar();}
		else
		{
			chr='d';
			cout << "Sorry, you have no more points left to spend.";
			Sleep(2000);
			system("cls");
		}
		stop=0;
		x=-1;
		switch(chr) // ask user for answer
		{
			case 's':
				x=0;
			break;
			case 'i':
				x=1;
			break;
			case 'a':
				x=2;
			break;
			case 'd':
				cout	<< "Thats all your points spent.\nThese are your new stats:\n"
						<< "\n Strength: " << points[0]
						<< "\n\nAre you happy with this choice?\ny - I want these stats\nn - I want to choose these stats again\n\nAnswer: ";
				switch(GetSingleChar());
				{
					case 'y';
						stop=1;
						//player.setSpts(sPts);//originally program gets points to spend from the player class. for now just set sPts to 5
						//player.setStr(player.getStr()+points[0]);//sets the class player's strength variable (int)
						validInput=1;
					break;
					case 'n'://reset variables and start again.
						for(int x=0;x>3;x++){points[x]=0;}//reset points
						//sPts = player.getSpts();//get skill points from player class
						sPts = 5;
						validInput=1;
					break;
					default:
						cout << "Default - Not a valid answer";
				}
			default:
				x=0;
				cout << "activated default!";
				Sleep(5000);
				stop=0;
		}
		if(x>=0)
		{
			do
			{
				cout << "Skill points left is " << sPts;
				if(x==0){cout<<"\n\nStrength: ";}
				if(x==1){cout<<"\n\nIntelligence: ";}
				if(x==2){cout<<"\n\nAgility: ";}
				p = GetNum();
				points[x] =+ p;
				if (points[x] <= sPts && points[x] >= 0)
				{
					sPts -= points[x];
					validInput = 1;
				}
				else {cout << "Can't use that many points!";}
			}while(!validInput);
			validInput = 0;
		}
	}while(!stop);
	stop=0;
return 0;
}

char GetSingleChar()
{
	bool stop(0);
	string user_input;
	user_input='\0';
	char newChar;
	newChar='\0';
	do
	{
		getline(cin, user_input);
		newChar += user_input[0];

		if(!newChar=='\0')
		{
		stop=1;
		}

	}while(!stop);
	return newChar;
}

int GetNum()
{
	int result(0);
	string text;
	istringstream iss;
	do
	{
		cin >> text;
		iss.clear();
		iss.str(text);

		if(!(iss >> result))
		{
			cerr << text <<" is not a number\n\nChoice: ";
		}

	} while(!iss);
	return result;
}

Last edited on
Topic archived. No new replies allowed.