将 "yy" 输入到 char 变量时创建的无限循环应该只接受单个字符,例如 'y' 或 'n',"nn" 不会破坏代码
Infinite loop created when inputting "yy" into a char variable that should only take a single character such as 'y' or 'n', "nn" does not break code
cont
函数中的代码询问用户是否想再次玩我的游戏。
代码在接收到正确的字符输入时工作,例如 'y' 或 'n' 以及它们的相应的大写字母变体,如果 'a' 或 [=65= 等无效输入,else
块将正常工作以循环函数] 已输入。
但是在测试 运行 期间,'yy' 的输入破坏了导致程序无限循环的代码,运行ning 不会只有这个 cont
函数,但我的 game
函数也是如此。
choice 存储为 char
变量。我想知道为什么在输入 'yy' 或 'yes'[= 等多字符输入时,代码甚至会继续 运行 47=]。有趣的是 'nn'、'ny' 和以 'n' 开头的多字符输入的其他变体不会导致任何问题并正确地导致 else if
按预期阻止 运行ning。打印出“感谢参与”。然后结束程序。
声明为 char
的变量可以接受大于 1 个字符的输入吗?它只取第一个值吗?如果是这样,为什么 'yy' 会导致循环,而不是程序 运行ning 通过接受值 'y' 还是 'Y'?我如何更改我的程序,以便 'yy' 的输入不再导致问题,没有针对输入的特定行,例如 'yy' 或 'yes'.
#include <iostream>
#include <string> // needed to use strings
#include <cstdlib> // needed to use random numbers
#include <ctime>
using namespace std;
// declaring functions
void cont();
void game();
void diceRoll();
// variable declaration
string playerName;
int balance; // stores player's balance
int bettingAmount; // amount being bet, input by player
int guess; // users input for guess
int dice; // stores the random number
char choice;
// main functions
int main()
{
srand(time(0)); // seeds the random number, generates random number
cout << "\n\t\t-=-=-= Dice Roll Game =-=-=-\n";
cout << "\n\nWhat's your name?\n";
getline(cin, playerName);
cout << "\nEnter your starting balance to play with : $";
cin >> balance;
game();
cont();
}
// function declaration
void cont()
{
cin >> choice;
if(choice == 'Y' || choice == 'y')
{
cout << "\n\n";
game();
}
else if (choice == 'N' || choice == 'n')
{
cout << "\n\nThanks for playing.";
}
else
{
cout << "\n\nInvalid input, please type 'y' or 'n'";
cont(); // calls itself (recursive function!!!)
}
}
void game()
{
do
{
cout << "\nYour current balance is $ " << balance << "\n";
cout << "Hey, " << playerName << ", enter amount to bet : $";
cin >> bettingAmount;
if(bettingAmount > balance)
cout << "\nBetting balance can't be more than current balance!\n" << "\nRe-enter bet\n";
} while(bettingAmount > balance);
// Get player's numbers
do
{
cout << "\nA dice will be rolled, guess the side facing up, any number between 1 and 6 : \n";
cin >> guess;
if(guess <= 0 || guess > 6 )
{
cout << "\nYour guess should be between 1 and 6\n" << "Re-enter guess:\n";
}
} while(guess <= 0 || guess > 6);
dice = rand() % 6+1;
diceRoll();
if (dice == guess)
{
cout << "\n\nYou guessed correctly! You won $" << (bettingAmount * 6);
balance = balance + (bettingAmount * 6);
}
else
{
cout << "\n\nYou guessed wrong. You lost $" << bettingAmount << "\n";
balance = balance - bettingAmount;
}
cout << "\n" << playerName << ", you now have a balance of $" << balance << "\n";
if (balance == 0)
{
cout << "You're out of money, game over";
}
cout << "\nDo you want to play again? type y or n : \n";
cont();
}
void diceRoll()
{
cout << "The winning number is " << dice << "\n";
}
Does it only take the first value?
是的,>>
格式化提取运算符,当为单个 char
值调用时,将读取第一个非空白字符,然后停止。之后的所有内容都未读。
why does 'yy' cause a loop
因为第一个“y”被读取,原因如上所述。第二个“y”仍未读。
这是一个非常常见的错误,也是对 >>
的误解。它 而不是 读取整行键入的输入。在跳过它前面的任何空格后,它只读取一个 value。
您的程序会停止,直到输入了整行输入,然后是 Enter
,但这不是 >>
读取的内容。它只读取它被要求读取的内容,而输入的所有其他内容都不会被读取。
于是程序继续执行,直到执行到这部分:
cin >> bettingAmount;
此时输入中的下一个未读字符是 y
。 >>
格式的提取运算符,对于int
这样的值bettingAmount
,需要数值输入(跟随可选的空格)。但是下一个字符不是数字。是字符 y
.
这导致格式化的 >>
提取运算符失败。 bettingAmount
中没有任何内容被读入。它完全没有被 >>
运算符改变。因为它是在全局范围内声明的,所以它是零初始化的。所以它仍然是 0.
除了 >>
提取运算符失败之外,作为失败的一部分,它将输入流设置为失败状态。当输入流处于失败状态时,所有后续输入操作都会自动失败而不做任何事情。这就是为什么您的程序会陷入无限循环。
虽然有一种方法可以将输入流从失败状态中清除,但这是一种笨拙的方法。干净的解决方案是修复读取输入的代码。
如果您的目的是停止程序并输入一些内容,然后输入 Enter
,那么这就是 std::getline
的用途。显示的程序使用它来读取一些初始输入。
阻力最小的路径是简单地使用std::getline
读取所有输入。不是使用 >>
读取单个字符,而是使用 std::getline
读取输入的下一行,进入 std::string
,然后检查字符串的第一个字符并查看它是什么。问题已解决。
cin >> bettingAmount;
你想在这里做同样的事情。否则你会 运行 遇到同样的问题:输入错误会导致输入操作失败,令人头疼。
你为什么需要这种头痛?只需使用 std::getline
将文本读入 std::string
,从中构造一个 std::istringstream
,然后在 std::istringstream
上使用 >>
,并检查其 return 值来判断是否失败。这是检查无效输入的简单方法,如果在此输入的不是数字输入,您可以完全自由地处理错误输入。
cont
函数中的代码询问用户是否想再次玩我的游戏。
代码在接收到正确的字符输入时工作,例如 'y' 或 'n' 以及它们的相应的大写字母变体,如果 'a' 或 [=65= 等无效输入,else
块将正常工作以循环函数] 已输入。
但是在测试 运行 期间,'yy' 的输入破坏了导致程序无限循环的代码,运行ning 不会只有这个 cont
函数,但我的 game
函数也是如此。
choice 存储为 char
变量。我想知道为什么在输入 'yy' 或 'yes'[= 等多字符输入时,代码甚至会继续 运行 47=]。有趣的是 'nn'、'ny' 和以 'n' 开头的多字符输入的其他变体不会导致任何问题并正确地导致 else if
按预期阻止 运行ning。打印出“感谢参与”。然后结束程序。
声明为 char
的变量可以接受大于 1 个字符的输入吗?它只取第一个值吗?如果是这样,为什么 'yy' 会导致循环,而不是程序 运行ning 通过接受值 'y' 还是 'Y'?我如何更改我的程序,以便 'yy' 的输入不再导致问题,没有针对输入的特定行,例如 'yy' 或 'yes'.
#include <iostream>
#include <string> // needed to use strings
#include <cstdlib> // needed to use random numbers
#include <ctime>
using namespace std;
// declaring functions
void cont();
void game();
void diceRoll();
// variable declaration
string playerName;
int balance; // stores player's balance
int bettingAmount; // amount being bet, input by player
int guess; // users input for guess
int dice; // stores the random number
char choice;
// main functions
int main()
{
srand(time(0)); // seeds the random number, generates random number
cout << "\n\t\t-=-=-= Dice Roll Game =-=-=-\n";
cout << "\n\nWhat's your name?\n";
getline(cin, playerName);
cout << "\nEnter your starting balance to play with : $";
cin >> balance;
game();
cont();
}
// function declaration
void cont()
{
cin >> choice;
if(choice == 'Y' || choice == 'y')
{
cout << "\n\n";
game();
}
else if (choice == 'N' || choice == 'n')
{
cout << "\n\nThanks for playing.";
}
else
{
cout << "\n\nInvalid input, please type 'y' or 'n'";
cont(); // calls itself (recursive function!!!)
}
}
void game()
{
do
{
cout << "\nYour current balance is $ " << balance << "\n";
cout << "Hey, " << playerName << ", enter amount to bet : $";
cin >> bettingAmount;
if(bettingAmount > balance)
cout << "\nBetting balance can't be more than current balance!\n" << "\nRe-enter bet\n";
} while(bettingAmount > balance);
// Get player's numbers
do
{
cout << "\nA dice will be rolled, guess the side facing up, any number between 1 and 6 : \n";
cin >> guess;
if(guess <= 0 || guess > 6 )
{
cout << "\nYour guess should be between 1 and 6\n" << "Re-enter guess:\n";
}
} while(guess <= 0 || guess > 6);
dice = rand() % 6+1;
diceRoll();
if (dice == guess)
{
cout << "\n\nYou guessed correctly! You won $" << (bettingAmount * 6);
balance = balance + (bettingAmount * 6);
}
else
{
cout << "\n\nYou guessed wrong. You lost $" << bettingAmount << "\n";
balance = balance - bettingAmount;
}
cout << "\n" << playerName << ", you now have a balance of $" << balance << "\n";
if (balance == 0)
{
cout << "You're out of money, game over";
}
cout << "\nDo you want to play again? type y or n : \n";
cont();
}
void diceRoll()
{
cout << "The winning number is " << dice << "\n";
}
Does it only take the first value?
是的,>>
格式化提取运算符,当为单个 char
值调用时,将读取第一个非空白字符,然后停止。之后的所有内容都未读。
why does 'yy' cause a loop
因为第一个“y”被读取,原因如上所述。第二个“y”仍未读。
这是一个非常常见的错误,也是对 >>
的误解。它 而不是 读取整行键入的输入。在跳过它前面的任何空格后,它只读取一个 value。
您的程序会停止,直到输入了整行输入,然后是 Enter
,但这不是 >>
读取的内容。它只读取它被要求读取的内容,而输入的所有其他内容都不会被读取。
于是程序继续执行,直到执行到这部分:
cin >> bettingAmount;
此时输入中的下一个未读字符是 y
。 >>
格式的提取运算符,对于int
这样的值bettingAmount
,需要数值输入(跟随可选的空格)。但是下一个字符不是数字。是字符 y
.
这导致格式化的 >>
提取运算符失败。 bettingAmount
中没有任何内容被读入。它完全没有被 >>
运算符改变。因为它是在全局范围内声明的,所以它是零初始化的。所以它仍然是 0.
除了 >>
提取运算符失败之外,作为失败的一部分,它将输入流设置为失败状态。当输入流处于失败状态时,所有后续输入操作都会自动失败而不做任何事情。这就是为什么您的程序会陷入无限循环。
虽然有一种方法可以将输入流从失败状态中清除,但这是一种笨拙的方法。干净的解决方案是修复读取输入的代码。
如果您的目的是停止程序并输入一些内容,然后输入 Enter
,那么这就是 std::getline
的用途。显示的程序使用它来读取一些初始输入。
阻力最小的路径是简单地使用std::getline
读取所有输入。不是使用 >>
读取单个字符,而是使用 std::getline
读取输入的下一行,进入 std::string
,然后检查字符串的第一个字符并查看它是什么。问题已解决。
cin >> bettingAmount;
你想在这里做同样的事情。否则你会 运行 遇到同样的问题:输入错误会导致输入操作失败,令人头疼。
你为什么需要这种头痛?只需使用 std::getline
将文本读入 std::string
,从中构造一个 std::istringstream
,然后在 std::istringstream
上使用 >>
,并检查其 return 值来判断是否失败。这是检查无效输入的简单方法,如果在此输入的不是数字输入,您可以完全自由地处理错误输入。