Need Help with Input Validation Loop

Hey everyone I am having trouble with my magic eight-ball program and any help would be greatly appreciated. 1. Magic Eight-Ball Program: Write a program that answers a question about the future! Use a loop to ask the user for a yes/no question about the future and input that question. Then ask the user to choose a number between 1 and 8. Use an input validation loop to ensure a number between 1 and 8. Display the question and the prediction (based on the number). Allow the user to keep asking questions until they enter Q to quit.
Use these answers:
1. It is certain.
2. Don’t count on it.
3. Without a doubt.
4. Outlook good.
5. My sources say no.
6. Signs point to yes.
7. My reply is no.
8. You may rely on it.

I got the basic program working, where the user asks a question and then picks a number 1-8 and then gets a response. It is when I tried to make the input validation loop to keep asking if they want to ask another question where I had trouble. If I type Y in, it just completely skips asking the user for a question and goes straight to asking them to pick a number.
This is my code so far:

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

using namespace std;

void main()
{
	string question;
	int choice;
	char again;
	

	do
	{
		cout << "Do you want to ask a question(Y/N)? ";
		cin >> again;

		//Get question
		cout << "Ask a question: ";
		getline(cin, question);
		
		//Get number
		cout << "Pick a number 1-8: ";
		cin >> choice;

		if (choice == 1) cout << "It is certain. " << endl;
		else if (choice == 2) cout << "Don't count on it." << endl;
		else if (choice == 3) cout << "Without a doubt." << endl;
		else if (choice == 4) cout << "Outlook good." << endl;
		else if (choice == 5) cout << "My sources say no." << endl;
		else if (choice == 6) cout << "Signs point to yes." << endl;
		else if (choice == 7) cout << "My reply is no." << endl;
		else if (choice == 8) cout << "You may rely on it." << endl;

	} while ((again == 'Y' || again == 'y'));
			
		cout << "Thanks for participating! " << endl;

	system("pause");

}
Last edited on
cin >> again; is formatted input; it skips white space (space, newline etc.) till it finds a non-white-space character, extracts the character and returns. If the user has pressed enter after 'Y' or 'N', that new line character will remain in the input buffer.

getline(cin, question); is unformatted input; it does not skip over anything. It reads in everything up to a newline, and if there is nothing before the new line, it reads an empty string.

So we need to extract and throw away that new line before attempting to read the question.
This can be done by adding the line
cin.ignore( 1000000, '\n' ) ; // remove the newline from input buffer
immediately after line 16 cin >> again;
http://www.cplusplus.com/reference/istream/istream/ignore/
Last edited on
JLBorges, thank you so much man this helped clear up that portion of my program. Now when I type 'Y' it works, but when I type 'N' it still works when it shouldn't. I thought because I put the while(again=='Y' || again=='y') that pretty much anything other than 'Y' or 'y' that gets typed in would just end the program.

Again thanks for the help man!
(again=='Y' || again=='y') is checked at the *end* of the loop, after cout << "Ask a question: "; etc.

The check (again=='Y' || again=='y') should be immediately after cin >> again;

This is one way of writing the loop so that we exit if the answer is not 'Y' or 'y':

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

int main() // note: main *must* return int
{
    char again ;
    while( std::cout << "Do you want to ask a question(Y/N)? " &&
           std::cin >> again &&
           (again == 'Y' || again == 'y') )
    {
        std::cin.ignore( 1000000, '\n' ) ; // throw the newline away

        std::string question ;
        std::cout << "Ask a question: ";
        std::getline( std::cin, question );

        int choice ;
        std::cout << "Pick a number 1-8: ";
        std::cin >> choice; // for now, we will assume that the user enters a number

        if (choice == 1) std::cout << "It is certain. \n" ;
        else if (choice == 2) std::cout << "Don't count on it.\n" ;
        else if (choice == 3) std::cout << "Without a doubt.\n" ;
        else if (choice == 4) std::cout << "Outlook good.\n" ;
        else if (choice == 5) std::cout << "My sources say no.\n" ;
        else if (choice == 6) std::cout << "Signs point to yes.\n" ;
        else if (choice == 7) std::cout << "My reply is no.\n" ;
        else if (choice == 8) std::cout << "You may rely on it.\n" ;
        else std::cout << "invalid choice.\n" ;
    }

    std::cout << "Thanks for participating!\n" ;
}
Oh so I don't even need to have the do statement, OK this helps a lot. Thanks for all the help man!
Topic archived. No new replies allowed.