user input bug

So technically the program works fine, but i'm trying to figure out a way to limit the amount of characters a user can input for my cin. If i put in multiple y's, such as "yyy", the program takes that and runs my loop 3 times. I wouldn't say its a problem considering this is just an assignment for my c++ class, and my professor is chill, I just want to know for my own understanding if there's anything i could do to either limit the characters of the cin or stop the program from running the loop multiple times from the multiple correct user inputs.


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

struct Monster
{
	string name;
	int combatpower;
};


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
#include <iostream>
#include "Monster.h"
#include <ctime>
using namespace std;

bool CaptureAttempt(Monster monster);
Monster SetMonster();
string RandomNameGenerator();

int main()
{
	srand(time(0));
	char input;
	bool didCatch = false;
	int pokeballs = 5;

	Monster monster = SetMonster();

	cout << "A wild " << monster.name << " appeared!" << endl << endl;
	cout << monster.name << endl;
	cout << monster.combatpower << endl << endl << endl;
	while (didCatch == false)
	{
		cout << "You have " << pokeballs << " pokeballs left" << endl;
		cout << "Attempt to capture? <Y/N> ";
		cin >> input; cout << endl;
		if (input == 'y' || input == 'Y')
		{
			pokeballs--;
			didCatch = CaptureAttempt(monster);
			if (didCatch == false)
			{
				cout << monster.name << " broke free! Attempt to catch again?" << endl << endl;
			}
				if (pokeballs == 0)
				{
					cout << "You do not have any pokeballs, so you ran and got away safely." << endl;
					break;
				}
		}
		if (input == 'n' || input == 'N')
		{
			cout << "Got away safely." << endl;
			break;
		}
	}
	if (didCatch == true)
	{
		cout << "Gotcha! You caught " << monster.name << "!" << endl;
	}	
	return 0;
}

bool CaptureAttempt(Monster monster)
{
	int chance;
			if (monster.combatpower < 100)
			{
				chance = rand() % 1;
				if (chance == 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else if (monster.combatpower > 99 && monster.combatpower < 201)
			{
				chance = rand() % 3;
				if (chance == 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else if (monster.combatpower > 200)
			{
				chance = rand() % 7;
				if (chance == 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
}

Monster SetMonster()
{
	Monster monster;
	monster.name = RandomNameGenerator();
	monster.combatpower = rand() % 450 + 1;
	return monster;
}

string RandomNameGenerator()
{
	const int size = 25;
	string names[size] =
	{
		"Charmander", "Bulbasaur", "Squirtle", "Pidgey", "Pikachu", "Sandshrew", "Zubat",
		"Mankey", "Abra", "Magikarp", "Eevee", "Rattata", "Vulpix", "Scyther", "Jigglypuff",
		"Geodude", "Onix", "Staryu", "Snorlax", "Mewtwo", "Oddish", "Caterpie", "Spearow",
		"Charizard", "Zapdos"
	};

	return names[rand() % 24];
}
Here's a compilable version that does what you want
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
#include <iostream>
#include <ctime>
#include <limits>
using namespace std;

int main()
{
	srand(time(0));
	char input;
	bool didCatch = false;
	int pokeballs = 5;

	cout << "A wild  appeared!" << endl << endl;
	while (didCatch == false)
	{
		cout << "You have " << pokeballs << " pokeballs left" << endl;
		cout << "Attempt to capture? <Y/N> ";
		cin >> input; cout << endl;
		if (input == 'y' || input == 'Y')
		{
            pokeballs--;
            if (rand() % 6 == 0)
                didCatch = true;
		}
		if (input == 'n' || input == 'N')
		{
			cout << "Got away safely." << endl;
		}
		
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}
	if (didCatch == true)
	{
		cout << "Gotcha! You caught !" << endl;
	}	
	return 0;
}

But sure to add #include <limits> to the top, in case you missed that.

https://stackoverflow.com/questions/5131647/why-would-we-call-cin-clear-and-cin-ignore-after-reading-input

The cin.clear() clears the error flag on cin (so that future I/O operations will work correctly), and then cin.ignore(10000, '\n') skips to the next newline (to ignore anything else on the same line as the non-number so that it does not cause another parse failure). It will only skip up to 10000 characters, so the code is assuming the user will not put in a very long, invalid line.


PS:
1
2
3
4
5
6
7
8
9
				chance = rand() % 1;
				if (chance == 0)
				{
					return true;
				}
				else
				{
					return false;
				}

This will always return true, since anything (mod 1) is 0.

Also, later instances can be simplified to this:
1
2
				chance = rand() % 7;
				return (chance == 0);


PPS:
Things like,
while (didCatch == false) { ... }
and especially,
 
if (didCatch == true) { ... }

are usually considered redundant, the easier way of saying this is
while (!didCatch) { ... }

if (didCatch) { ... }

Because it's a boolean value, the condition already is directly translated into true or false.
Last edited on
Topic archived. No new replies allowed.