cin and int and options

so my friend just got into programming and I've been helping him a little bit, he has to do the console game as a school "project" (first grade), well, everything was fine untill we went into more "detailed" versions of options:

1. you enter your name (works fine)
2. you are greeted with message for 4 sec (works fine)
3. game tells you in what room you are, now you have 2 options, go to next room? (Y/N), this WORKS if you use y/Y, n/N, it even gives you error when you enter anything else, BUT when you enter MORE characters, e.g. instead of "y" you do "yes", then it will run the code 3 times but it WILL accept it as a "y" because it has "y" as the first element, so when you say something like "qwe" it will give you error like you entered invalid choice, therefore it gets the first char and works with it, but the console will go thru the code as many times as you entered characters
4. YES option - now it will list you the rooms that you can go to, if you will select ID of EXISTING room, that you ARE ABLE to go to, it will just move you there, if you will enter ID of nonexisting room or the room you're not allowed to go, it will give you error saying that you can't go there, this works fine, HOWEVER there's SAME problem, as with the "y/n" option, therefore when you enter a char (instead of int in this case) it will go to the infinite loop without asking you questions again

so again, if you enter correct values (only 1 char for y/n option, INT for a room option), it works fine, it's getting terribly bugged with array of chars for y/n and any char for room option, and since I personally kinda hate chars (I'm just using strings all the time because of problems like this), I really have no idea what to do in here, and my friend doesn't want to use strings because he kinda knew only if/else yesterday and today he has fully dynamic room creation with room entries and stuff (basically I skipped like 1 month of lectures of basic c++ and included it everything in 1 day)

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
while(true) // loop of the functions 
	{
		system("cls");

		if(cRoom == 0)
			cout << "You can't go to that room!" << endl;
		if(cValue == 0)
			cout << "Please enter correct value!" << endl;

		cout << "You are in room: " << sRoomName[iCurrRoom] << endl; // error message for invalid input 

		if(iCurrRoom == ROOM_DRAGON) // several structions for room with dragon
			ExecuteFight(ROOM_DRAGON); 
		else if(iCurrRoom == ROOM_KING) // function in room king 
			ExecuteFight(ROOM_KING);
		else if(iCurrRoom >= ROOM_TREASURE1 && iCurrRoom <= ROOM_TREASURE4) // function for random loot 
			RandomLoot();

		char cGoToOther;
		cout << "Do you want to go to other room ? (Y/N)\n"; // function for changing rooms 
		cin >> cGoToOther;
		if(cGoToOther == 'y' || cGoToOther == 'Y')
		{
			system("cls");
			ShowPossibleRooms(iCurrRoom);
			int iNextRoom;
			cin >> iNextRoom;
			if(iNextRoom < 0 || iNextRoom >= ROOM_MAX)
			{
				cRoom = 0;
				cValue = 1;
			}
			else
			{
				cRoom = GoToRoom(iNextRoom);
				cValue = 1;
			}
		}

		else if (cGoToOther == 'n' || cGoToOther == 'N')
			return 0;
		else
		{
			cValue = 0;
			cRoom = 1;
		}
	}
Last edited on
bump
Actually, what happens if they enter more than a thousand characters? Much better to do this instead:
 
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

You also need to #include <limits>.

For the part (4), you can probably do something to test if the failbit is set, and then handle the error. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int iNextRoom;
while (!cin >> iNextRoom) {        // while reading in iNextRoom fails
    std::cin.clear();              // Clear the error bit

    // Now we remove extra characters, so that it doesn't do this for every
    // letter that they put in before the number:
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    // Tell the player that an error has occured
    std::cout << "Invalid input!" << std::endl;

    // Print the possible rooms again, and loop until valid input is given.
    ShowPossibleRooms(iCurrRoom)
}

// Continue on with code 
Last edited on
thanks! that greatly helped, however I'm still having problems with the second (4. point) problem, I also tried to use if(cin >> iNextRoom) before but it did take me to the infinite loop anyway, HOWEVER now it doesnt take me to the infinite loop, now it will just do the loop 2 times and starts working normally, actually, it will perform everything since first CLS (after while statement) till the cin >> cGoToOther;

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
	while(true) // loop of the functions 
	{
		system("cls");

		if(cRoom == 0)
			cout << "You can't go to that room!" << endl;
		if(cValue == 0)
			cout << "Please enter correct value!" << endl;

		cout << "You are in room: " << sRoomName[iCurrRoom] << endl; // error message for invalid input 
		
		if(cValue != 0)
		{
			if(iCurrRoom == ROOM_DRAGON) // several structions for room with dragon
				ExecuteFight(ROOM_DRAGON); 
			else if(iCurrRoom == ROOM_KING) // function in room king 
				ExecuteFight(ROOM_KING);
			else if(iCurrRoom >= ROOM_TREASURE1 && iCurrRoom <= ROOM_TREASURE4) // function for random loot 
				RandomLoot();
		}

		char cGoToOther;
		cout << "Do you want to go to other room ? (Y/N)\n"; // function for changing rooms 
		cin >> cGoToOther;
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		if(cGoToOther == 'y' || cGoToOther == 'Y')
		{
			system("cls");
			ShowPossibleRooms(iCurrRoom);
			int iNextRoom;
			if(cin >> iNextRoom)
			{
				if(iNextRoom < 0 || iNextRoom >= ROOM_MAX)
				{
					cRoom = 0;
					cValue = 1;
				}
				else
				{
					cRoom = GoToRoom(iNextRoom);
					cValue = 1;
				}
			}
			else
			{
				cin.clear();
				cRoom = 1;
				cValue = 0;
			}
		}
		else if (cGoToOther	==	'n'	||	cGoToOther	==	'N')
			return 0;
		else
		{
			cValue = 0;
			cRoom = 1;
		}
	}


what is the reason for it to do half of the code 2 times ?
OK, your problem is that you are doing if(cin >> iNextRoom) rather than while(cin >> iNextRoom). What is happening is that the program execution is reaching that point and inputting the value. If cin returns non-0, then all is good, and your logic goes on. However, otherwise, it does the "else" statement and go to the beginning of the loop. Instead, what you may want to do is something to allow you to keep looping through UNTIL cin returns an error. This would be my way of doing it (there are probably better ways, though):
1
2
3
4
5
6
7
8
9
int iNextRoom;
while (!std::cin >> iNextRoom) {
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max, '\n');
    std::cout << "Please enter a valid integer." << std::endl;
}

if (iNextRoom < 0 || iNextRoom >= ROOM_MAX)
//etc... 
I actually added cin.ignore(numeric_limits<streamsize>::max(), '\n'); to the else of cin >> iNextRoom, so it's cin.clear(), cin.ignore(...), cRoom = 1 and cValue = 0, it works just fine, but im not sure if this is the good way
Topic archived. No new replies allowed.