如何跟踪已经在 C++ 的刽子手游戏中猜到的字母?
Posted
技术标签:
【中文标题】如何跟踪已经在 C++ 的刽子手游戏中猜到的字母?【英文标题】:How to keep track of letters already guessed in Hangman game for C++? 【发布时间】:2014-07-20 05:09:06 【问题描述】:给我的这个任务是从我们的教科书中复制一个刽子手游戏,并将其修改为书中的具体说明。我花了很多时间试图研究这个问题,并找到我不断收到与我相同的错误消息的原因。在我所见的任何地方,所有尝试修改此代码的人都尝试过使用数组,并且和我一样幸运。我目前正在编写 Strings 的一章,并计划按照 String 中的说明执行我的大部分语句。
我需要在这段代码中修改的是:
-
跟踪用户输入的所有字母
如果用户输入了已输入的字母,则向用户发送错误消息
我遇到的主要问题是,当我编译这段代码并输入我已经输入的同一个字母时,它会以以下消息终止:
在抛出 'std::out of range' 的实例后调用终止 what(): basic_string::substr
#include <iostream>
#include <string>
using namespace std;
int main()
//declare variables
string origWord = " ";
string letter = " ";
char dashReplaced = 'N';
char gameOver = 'N';
int numIncorrect = 10;
string displayWord = "-----";
string usedLetter = " ";
string letterNotGuessedYet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int letterPlace = 0;
//get original word
do //begin loop
cout << "Enter a 5-letter word in uppercase: ";
getline(cin,origWord);
while(origWord.length() != 5); //end do loop
//clear the screen
system("cls");
//start guessing
cout <<"Guess this word: " << displayWord << endl;
while(gameOver =='N')
cout << "Enter an uppercase letter: ";
cin >> letter;
//This provides the letterPlace value with the possition of the
//input letter by the user within letterNotGuessedYet
letterPlace = letterNotGuessedYet.find(letter,0);
//This statement determines if the letter input by the user is
//still in the letterNotGuessYet string.
if(letterNotGuessedYet.substr(letterPlace,1)== letter)
letterNotGuessedYet.replace(letterPlace, 1, "*");
//cout << endl << letterNotGuessedYet; //This tests that a letter is being replaced with an *
else
cout << "The letter " << letter << " has already been used. Choose another letter." << endl << endl;
// end if
//search for the letter in the original word
for(int x = 0; x < 5; x++)
//if the current character matches
//the letter, replace the corresponding
//dash in the displayWOrd variable and then
//set the dashReplaced variable to 'Y'
if (origWord.substr(x,1) == letter)
displayWord.replace(x, 1, letter);
dashReplaced = 'Y';
//end if
//end for
//if a dash was replaced, check whether the
//displayWord variable contains any dashes
if (dashReplaced == 'Y')
//if the displayWord variable does not
//contain any dashes, the game is over
if (displayWord.find("-",0) == -1)
gameOver = 'Y';
cout << endl << "Yes, the word is " << origWord << endl;
cout << "Great guessing!" << endl;
else //otherwise, continue guessing
cout << endl<< "Guess this word: " << displayWord << endl;
dashReplaced = 'N';
//end if
else //processed when dashReplaced contains 'N'
//minus 1 to the number of incorrect gueses left
numIncorrect += 1;
//if the number of incorrect guesses is 10,
//the game is over
if (numIncorrect == 10)
gameOver = 'Y';
cout << endl << "Sorry, the word is " << origWord << endl;
//end if
//end if
//end while
//system("pause");
return 0;
//end of main function
我认为我收到此错误的原因与以下代码有关:
//This provides the letterPlace value with the possition of the
//input letter by the user within letterNotGuessedYet
letterPlace = letterNotGuessedYet.find(letter,0);
//This statement determines if the letter input by the user is
//still in the letterNotGuessYet string.
if(letterNotGuessedYet.substr(letterPlace,1)== letter)
letterNotGuessedYet.replace(letterPlace, 1, "*");
//cout << endl << letterNotGuessedYet; //This tests that a letter is being replaced with an *
else
cout << "The letter " << letter << " has already been used. Choose another letter." << endl << endl;
// end if
感谢您为我提供的任何帮助。
【问题讨论】:
问题是使用std::string::find
函数的返回值而不测试它。问题是使用 std::string::find
函数的返回值而不对其进行测试。如果未找到子字符串,则其return value 可以是特殊值npos
。如果您在 substr
中使用该值,则它位于无效索引中,这会导致您看到的异常。
现在是学习调试的好时机。 SO 不是调试服务。你需要自己做这部分。启动您的调试器,指示它在异常抛出站点停止,检查您的变量,找出哪个是哪个数组的越界索引,找出导致这种情况的逻辑错误,修复,重复。如果您在启动和运行调试器以及做您想做的事情时遇到问题,请提出不同的问题。
感谢 NicholasM,该链接和您的解释帮助我了解了发生了什么。
【参考方案1】:
您收到错误的原因是因为您在测试之前使用了“letterPlace”值来查看它是否真的被发现。如果“string::find”没有找到任何东西,它将返回一个值“string::npos”。在尝试使用它之前,您需要测试该值的 letterPlace 变量。
letterPlace = letterNotGuessedYet.find(letter,0);
// Check to see if this letter is still in the "letterNotGuessedYet string
if(letterPlace != string::npos)
// At this point the letter is in the letterNotGuessedYet string so let it go
letterNotGuessedYet.replace(letterPlace, 1, "*");
else
// The letter was not found which means it has already been guessed.
// Show error to the user here
cout << "The letter " << letter << " has already been used. Choose another letter." << endl << endl;
【讨论】:
以上是关于如何跟踪已经在 C++ 的刽子手游戏中猜到的字母?的主要内容,如果未能解决你的问题,请参考以下文章