所以基本上我今天已经在这个循环上工作了大约7个小时。它没有按照我认为的那样表现。当我使用cin进入失败状态时(row是一个char,列是一个int,所以如果例如我输入aa1而不是a1),它会在请求新coord之前调用无效Coord两次。
do
{
confirmShot = false;
validShot = false;
failShot = false;
cout << enterCoord;
cin >> row >> column;
if (cin.fail())
{
cin.clear();
cout << invalidCoord << endl;
failShot = false;
continue;
}
if (failShot == true)
{
row = toupper(row);
xCoord = column - 1;
yCoord = static_cast<int>(row - 'A');
if(xCoord > 9 || xCoord < 0 || yCoord > 9 || yCoord < 0)
{
cout << invalidCoord << endl;
validShot = false;
}
else
{
validShot = true;
}
}
else
{
continue;
}
currentTile = tileToSymbol(computerBoard[xCoord][yCoord]);
if (validShot == true)
{
switch(currentTile)
{
case '~':
case 'a':
case 'b':
case 's':
case 'd':
case 'p':
cout << "You have already shot at " << row << column << "." << '\n'
<< "Please pick a new coordinate!" << endl;
validShot = false;
confirmShot = false;
break;
default:
confirmShot = true;
}
}
else
{
continue;
}
}
while(!confirmShot);
输出:
Your shot: Enter the coordinates for a shot (e.g. B2) cc2
Invalid coordinates!
Pick a row value between A and J
and a column value between 1 and 10.
Enter the coordinates for a shot (e.g. B2) Enter the coordinates for a shot (e.g. B2) cc2
Invalid coordinates!
Pick a row value between A and J
and a column value between 1 and 10.
Enter the coordinates for a shot (e.g. B2) Enter the coordinates for a shot (e.g. B2) c2
Enter the coordinates for a shot (e.g. B2) c2
此外,我不知道如何让do… while循环退出。在我意识到如果有人输入非整数作为第二个字符,我必须处理失败状态之前,它曾经退出得很好。
我添加了“继续”代码,因为与我交谈的人说我需要它跳到下一个部分,如果我删除它,程序就会锁定,尽管在我尝试处理故障状态之前,我没有继续代码,它工作得很好。
我真的只需要让这个循环正常工作,但是我已经用尽了我的能力。我如何处理故障状态,保持无效Coord两次显示(老实说,我不知道它为什么这样做),在收到有效输入后退出循环,并保存一天?
我可能过于简化了,如果我错了,请评论,但我认为错误只是在你的if语句中。
看起来好像if(ailShot==true)
从未被调用过,因为ailShot
被初始化为false,并且只有在您检查if(cin.fail())
时才会再次更新为false。如果我理解得没错,如果您的cin
没有失败,您希望if(ailShot==true)
被调用。在这种情况下,将ailShot初始化为True将修复您的错误。
尝试更改:
failShot = false;
到:
failShot = true;
好的,你的问题是理解对象中的std::c。
这就是它的工作原理
std::c在
开始于位置pos_typep=-1
然后递增这个位置,因为它从键盘缓冲区中获取字符,当它在解析输入的字符时遇到错误时,它将位置设置为eof
,所以当它下次运行时,它将返回eof
然后什么也不做。
要在您的代码中说明这一点,请在:cin下插入此片段
cin << row << column ;
cout << "p =" << cin.tellg();
它将输出以下内容(此处仅打印有趣的部分)
// when you enter for expel: c1 - which is correct input, it prints
p = 2; // advanced two position in the buffer until EOF
// when you enter wrong input: cc1 - it prints
p =-1;
// next run just after the error message, it will print
p = 3;//this number is the number of character read last time and it coincide with EOF
// right after, it will prompt you for another input
这意味着std::c
需要消耗缓冲区中的所有字符,然后将位置指示器设置为-1,然后再次开始提取字符。
这就是为什么你有一条重复的消息。那么如何修复它呢?
这是一个丑陋的黑客:
//inside the loop under
cin.clear()
cin.seekg(0); // rewind...uuurrrgg, ugly!! but it works
我的建议是重构你的代码。使用布尔逻辑来设计一个漂亮的代码流程图。代码库中出现这样的错误,意味着代码更多的是意大利面条代码,而不是编写良好的代码。
尽你所能,祝你好运!