在输入输入之前,在空格中读取getline()函数

时间:2014-10-25 22:40:22

标签: c++ visual-studio-2012 c++11

好吧,我写了一个刽子手游戏。除了用户完成游戏后,游戏效果很好,并输入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;
}

2 个答案:

答案 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吞噬丢失的空格(包括换行符)。