我正在为学校项目创建一个非常简单的数字猜谜游戏,并且在重复主菜单时遇到问题。我使用 do-while循环创建它,而我遇到的问题是菜单选择变量是 int ,所以当我(或用户)进入时从菜单中选择时,非int 意外输入主循环结束时的}while(condition)
无法捕获它并且程序无限重复。相反,如果您在菜单选择中输入 invalid int ,程序将捕获它,显示“无效输入”消息,然后重复主菜单。
很难用书面形式解释我的意思,所以这里的源代码的相关行用星号表示。我保存为.cpp并使用g++ -ansi -pedantic -Wall -Werror
在linux中进行编译。教师禁止在条件语句中进行硬编码,因此是全局常量。
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
const int PLAY = 1, HIGH_SCORE = 2, EXIT = 3;
const char YES = 'y', NO = 'n';
int main()
{
// Randomly generated value
int randomNumber;
// User input
int userGuess, menuChoice;
char repeat;
// Calculated value
int numberOfGuesses;
// Place-holder values (to be replaced by calculated values)
int score1 = 1000, score2 = 2000, score3 = 3000;
cout << endl << endl;
cout << "Greetings! This is a number guessing game where I think of" << endl
<< "a whole number between one and ten and you try to guess it!" << endl
<< "You can guess as many times as you like, so don't be afraid" << endl
<< "to use trial and error, but your score is based on the " << endl
<< "number of guesses you make (the lower the better) so don't " << endl
<< "guess too haphazardly. Remember, only guess whole numbers!" << endl
<< endl;
do
{
cout << endl << "Main menu." << endl
<< "1. Play game" << endl
<< "2. Display high scores" << endl
<< "3. Exit game" << endl
<< "Please select an option: ";
cin >> menuChoice;
if (cin.fail()){
cout << "Please enter a valid choice" << endl;
continue;
}
cin.ignore();
switch(menuChoice)
{
case PLAY:
do
{
unsigned seed = time(0);
srand(seed);
randomNumber = 1 + rand() % 10;
cout << endl << "Press enter when you're ready to begin!";
cin.ignore();
cout << "Ok I thought of one!" << endl << endl;
numberOfGuesses = 0;
do
{
numberOfGuesses++;
cout << "Enter your guess: ";
cin >> userGuess;
cin.ignore();
// Check user's guess
if (userGuess == randomNumber)
cout << "Correct! That was impressive!" << endl << endl;
else if (userGuess < randomNumber)
cout << "Not quite, you guessed low." << endl << endl;
else if (userGuess > randomNumber)
cout << "Not quite, you guessed high." << endl << endl;
}while (userGuess != randomNumber);
cout << "Your score for this game was " << numberOfGuesses << endl;
// Determine if a high score was beaten
if (numberOfGuesses <= score1)
{
score3 = score2;
score2 = score1;
score1 = numberOfGuesses;
cout << "That's a new all time high score!" << endl;
}
else if (numberOfGuesses <= score2)
{
score3 = score2;
score2 = numberOfGuesses;
cout << "That's a new high score!" << endl;
}
else if (numberOfGuesses <= score3)
{
score3 = numberOfGuesses;
cout << "That's a new high score!" << endl;
}
else
{
cout << endl;
}
cout << "Would you like to play again? y/n: ";
cin.get(repeat);
cin.ignore();
while (tolower(repeat) != YES && tolower(repeat) != NO)
{
cout << endl;
cout << "Sorry, that is an invalid choice." << endl
<< "Please enter 'y' for yes or 'n' for no: ";
cin.get(repeat);
cin.ignore();
}
}while (tolower(repeat) == YES);
break;
case HIGH_SCORE:
cout << endl << "High Score 1: " << score1 << endl
<< "High Score 2: " << score2 << endl
<< "High Score 3: " << score3 << endl << endl;
cout << "Press enter to continue. ";
cin.ignore();
break;
case EXIT:
cout << endl << "Thanks for playing, I'll see you next time!" << endl << endl;
break;
default:
cout << endl << "That is an invalid selection, please enter '1', '2' or '3'"
<< endl;
break;
}
}while (menuChoice != EXIT);
return 0;
}
代码就当前答案编辑。
如果您需要更多信息,请告诉我,谢谢您的提前!
答案 0 :(得分:0)
像这样使用cin.fail()
(而不只是cin >> menuChoice;
)(以this post为模型):
cin >> menuChoice;
if (cin.fail()) {
cout << "Please enter a valid choice" << endl;
cin.clear();
cin.ignore();
continue;
}
//Remove the cin.ignore() at this place!
有关详细信息,请参阅this SO thread
答案 1 :(得分:0)
通过使用do-while并在循环外提示用户,您可以假设用户想要玩一次游戏,但可能并非如此。
更清洁的方法IMO将使用while循环。显示菜单循环外和循环结束。用户可以选择立即退出。
cout << "Greetings.....
cout << menu
// Get menuChoice input here.
while(menuChoice != EXIT){
...
cout << menu //reprompt at end to continue or exit cleanly
// Get menuChoice input here
}
do{
if(!cin){
cout << "Invalid input"
cin.clear()
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}while(!(cin >> menuChoice)) // This gets console input. If fail, loop.
numeric_limits<streamsize>::max()
完全清除
缓冲。 cin.clear()
重置cin
上的失败标记,以便它不会
总是假的。 cin.fail()
没问题。但有些人会认为!cin
更自然。