当执行while循环时,会发生一些非常奇怪的错误

时间:2018-12-10 05:43:31

标签: c++ validation debugging while-loop switch-statement

所以我基本上是在写基于海战游戏机的游戏。我实际上是在为游戏菜单编写函数。执行时,它工作正常,除了一些奇怪的故障。

  • 当我输入无效的 float 值时,该值包含从1到4的数字作为有效数字(例如7.4),它将显示标准错误消息,但还会执行与该数字相对应的命令(7.4将触发一条错误消息,但过一会儿就会退出程序,就好像用户输入数字“ 4”作为输入一样,任何x。[1-4]数字也是如此)
  • 当用户输入错误类型的多个无效字符作为输入时,会发生另一种奇怪但无害的故障。例如,如果用户输入“ !!!!!!”,则控制台将在请求其他输入之前显示6次错误消息。

这是出现问题的代码片段。情况1至3尚未完成,因此目前为空白。

std::cout << "Press a corresponding number for each action you want to do.\n\n1. Play Game\n2. Instructions\n3. Options\n4. Exit\n\n";
short int PlayerChoice;
std::cin >> PlayerChoice;
while (PlayerChoice != 1 && PlayerChoice != 2 && PlayerChoice != 3 && PlayerChoice != 4) // In case the user will enter the invalid/incorrect input or number
{ 
    std::cin.clear();
    std::cin.ignore(); // Prevents infinite loop from happening if user enters a char value
    std::cout << "Wrong input, please input a correct number between 1 and 4 (inclusive)\n";
    std::cin >> PlayerChoice;
}
switch (PlayerChoice){
case 1:
    Sleep(850);

    break;
case 2:
    Sleep(850);

    break;
case 3:
    Sleep(850);

    break;
case 4:
    Sleep(850);
    std::cout << "You have decided to exit the game.\n";
    Sleep(1500);
    std::cout << "Thanks for playing and hope to see you soon!";
    Sleep(3000);
    exit(0);
    break;
default: // This section actually isn't supposed to be executed under any circumstances
    std::cout << "Unexpected error occured. Terminating the programme.";
    break;
    }

为了更清楚一点,这里是the screenshot of what I mean

我对C ++还是比较陌生,所以任何C ++教授都可以解释这些bug的本质,并就如何解决此问题给我一些建议吗?提前非常感谢!

1 个答案:

答案 0 :(得分:1)

首先,通常不建议直接使用std::cin >> PlayerChoice;。它不检查用户输入错误。相反,最好使用std::cin.getline()并检查整行的语法。例如,如果用户输入“ 2 3 1 5 4”,则“ 2”将进入以触发您的选项2,但是所有其余输入都被缓冲。之后,您的下一个std::cin(整数)将收到“ 3”,而无需再次询问用户。

您获得的结果对我来说很奇怪,但是我尝试解释一下:

输入7.4后,由于您的程序指示它接收整数,因此7进入。因此它会打印“错误的输入...”错误消息。但是在下一个循环中,您的std::cin.ignore()不会清除缓冲区(这是我不知道为什么的原因。根据std::cin.ignored()手册,它应该清除。)然后,“。”将被忽略,因为它不是数字,并输入“ 4”。它会触发您选择“ 4”以结束程序。

实际上,如果将std::cin.ignore()更改为std::cin.ignore('\n'),则可以使用。

更新: 现在,我知道您的std::cin.ignore()为何不起作用:根据手册,如果未提供第一个参数nn = 1。因此,您只是忽略了1个字节。请阅读std::basic_istream::ignore手册。