好吧,我写了一个刽子手游戏。除了用户完成游戏后,游戏效果很好,并输入Y的char值再次播放。
我在do-while循环开始时将问题追溯到getline()函数。如果我输入Y,那么do-while循环会成功重复,但getline函数似乎已经认为cin中有输入,即使我没有输入任何内容。
到目前为止,这是我的代码:
#include<iostream>
#include<string>
using namespace std;
int main() {
string secretWord;
string secretWordClean = "";
string guessedLetters; //to be loaded with _ characters equal to length of secretWord
string incorrectlyGuessedChars = "";
char individualCharGuess;
char playAgain;
size_t countOfLetters = 0; //begine count at 0
size_t guessesRemaining;
int guessedUsed;
begin_game://label which we can use to bring us back to the start of the do-while loop at any time
do{//start of the game
cout << "Please enter a secret word: ";
getline(cin, secretWord); //y getline is cuaing the issue
for(int i = 0; i < secretWord.length(); i++){
if (isalpha(secretWord[i])){
secretWordClean += secretWord[i];
}
}
secretWord = secretWordClean; //assign all alpha secret word string back to original variable for better readability
guessesRemaining = secretWord.length() * 2;
for(int i = 0; i < secretWord.length(); i++){
guessedLetters += "_"; //fills guessedLetters with blanks equal to the length of the secretWord
}
cout << "Please guess a letter, you have " << guessesRemaining << " guesses remaining!" << endl;
cin >> individualCharGuess;
for(int i = 0; i < secretWord.length(); i++){ //every complete iteration of this for loop = one single guess
if(secretWord[i] == individualCharGuess){
guessedLetters[i] = individualCharGuess; //will replace the spaces with the correct character, if guessed
countOfLetters++; //if any letter is guessed correctly, this indicator will be inrimented above 0
continue;
}
if(secretWord.find(individualCharGuess) == string::npos){
if(incorrectlyGuessedChars.find(individualCharGuess) == string::npos){
incorrectlyGuessedChars += individualCharGuess;
}
}
}
if(secretWord.compare(guessedLetters) == 0){
cout << "You win! The word was: " << secretWord << endl;
guessedUsed = ((secretWord.length() * 2) - guessesRemaining) + 1 ;
cout << "You used " << guessedUsed << " guesses." << endl;
cout << "Play again? Enter Y for Yes, or anything else to exit: ";
cin >> playAgain;
if(playAgain != 'Y'){
break; //exit the loop if user guesses all the letters and doesn't want to play again
}
else {
goto begin_game;
}
}
guessesRemaining--; //we decriment our total guesses remaining if the user does not win the game or run out of guesses
if(countOfLetters > 0){
cout << "You have correctly guessed a letter!" << endl;
cout << "Here are the letters you have guessed correctly so far: ";
cout << guessedLetters << endl;
cout << "Here are the letters you have guessed incorrectly so far: ";
cout << incorrectlyGuessedChars << endl;
countOfLetters = 0; //reset the counter to prepare for next iteration of do-while loop
}
else if (guessesRemaining <= 0) {
cout << "You have run out of guesses!" << endl;
cout << "Here are the letters that you guessed correctly: ";
cout << guessedLetters << endl;
cout << "Here are the letters you guessed incorrectly: ";
cout << incorrectlyGuessedChars << endl;
cout << "The secret word was: " << secretWord << endl;
cout << "Play again? Enter Y for Yes, or anything else to exit: ";
cin >> playAgain;
if(playAgain != 'Y'){
break; //exit the loop if user guesses all the letters and doesn't want to play again
}
else goto begin_game;
}
else {
cout << "You guessed wrong! Keep trying, " << guessesRemaining << " guesses to go!" << endl;
cout << "Here are the letters you have guessed correctly so far: ";
cout << guessedLetters << endl;
cout << "Here are the letters you have guessed incorrectly so far: ";
cout << incorrectlyGuessedChars << endl;
}
}while (secretWord.compare(guessedLetters) != 0 || guessesRemaining != 0); //use to repeat the request for a single char guess
return 0;
}
答案 0 :(得分:5)
您正在混合格式化和未格式化的I / O:读取字符后,读取字符将立即停止。由于在输入字符后输入换行符,换行符仍然在流中,读取getline()
以终止该行。在使用std::getline()
之前,您应该跳过前导空格,例如:
if (std::getline(std::cin >> std::ws, s)) {
...
}
或者,您可以使用ignore()
忽略所有字符,包括换行符。请注意,忽略一个字符将无法作为'\n'
之间的一系列空格可靠地工作。要使用ignore()
,您应该使用正确的幻数:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
顺便说一句,你也应该总是验证输入是否真的成功,否则你很容易得到不正确的行为。
答案 1 :(得分:2)
不要使用>>
混合令牌提取和使用getline
进行线提取。前者不会删除换行符,因此令牌提取后的下一个getline
调用最终可能会读取前一行的剩余位,这可能是一个空字符串。
如果您必须混合使用这两种输入,请在使用std::cin >> std::ws
之前使用getline
吞噬丢失的空格(包括换行符)。