【问题标题】:while statement is unable to read the correct char inputwhile 语句无法读取正确的字符输入
【发布时间】:2014-07-01 08:01:49
【问题描述】:

嗨,我是 C++ 新手,我不明白为什么我的 while 语句现在不起作用。当我早些时候尝试这样做时,它正在工作。

完整代码见:http://pastebin.com/aeH5fKwh

这里基本上是while循环(我排除了所有不必要的部分,为了查看目的,我保留了while循环的内部)

int main()
{
unsigned int seed;
char input;
bool done;


for (int round = 0; round < 5; round++)
{
    done = false;
    cout << "\nEnter seed: ";
    cin >> seed;
    cout << "\nRound 1" << endl;

    while(!done)
    {
        cout << "\nDo you wish to draw another card [y][n]: ";
        cin >> input;

        while (input != 'y' && input != 'n')
        {
            cout << "Invalid input! Please enter [y][n]!" << endl;
            cin >> input;
        }
        if (input == 'y')
        {
            dealExtra(playerHand, deck, gameInfo);
            cout << "Your cards are ";
            printHand(playerHand, gameInfo.playerCardCount);
        }
        else
            done = true;
    }
}
cout << endl;
return 0;
}

当我尝试输入任何不是“y”、“n”的内容时,它会告诉我我的输入无效。但是当我尝试输入 'y' 或 'n' 时,它只是忽略了它,没有发生任何其他事情。我检查了 cout 语句,发现它设法进入 if (input == 'y') 语句,但它似乎没有做任何其他事情。直到 20 分钟前一切都很好,我真的不知道出了什么问题。

编辑:我使用 "cout

 Do you wish to draw another card [y][n]: y
 [y]
 y
 y
 y
 y

我使用 g++ 在 linux 终端上编译了这个

如果需要额外的代码,我会编辑并添加它们。谢谢!

【问题讨论】:

  • 您没有检查输入错误。此外,可能有输入缓冲处于活动状态。无论如何,在寻求帮助时,请始终尝试提供一个最小的、可编译的示例来展示您的错误。我建议阅读 How to Debug Small Programs 以更好地了解如何调试它。
  • 内部 while 循环的逻辑条件应该多考虑一点,通过手动跟踪不同的输入值并生成逻辑表。了解 C++ 如何短路逻辑条件也将有所帮助。请参阅此内容以供参考:Logical operators
  • 我已按照建议编辑了这篇文章.. 并将完整的代码包含在 pastebin 链接中,以防万一它有帮助.. 同时,我会照你说的做,看看调试小程序指南..谢谢
  • it kinda just ignored it and nothing else happenedit doesnt seem like it is doing anything else 是非常模糊的陈述。你到底是什么意思?
  • 是的。我不明白为什么它在 30 分钟前工作正常时忽略了我的输入。我根本没有编辑该部分。我尝试使用 cout 和 cerr 语句来确保它确实到达了我想要它去的地方..

标签: c++


【解决方案1】:

当您从控制台请求输入时,大多数实现会缓冲字符,直到按下换行键。

收到换行符后,返回缓冲区的第一个字符。 换行符以及任何额外的字符仍然保留在缓冲区中。

在您的情况下,第二个 cin &gt;&gt; input 语句将从缓冲区中读取换行符。

作为一个实验,尝试输入“frog”并单步执行您的程序。这应该说明缓冲区中残留字符的情况。

在第一个 cin &gt;&gt; input 之后尝试 cin.ignore(1000, '\n')ignore 方法将吃掉缓冲区中的所有剩余字符,直到找到换行符。

【讨论】:

    【解决方案2】:

    checkComputerHand 内部有一个无限循环:

    bool done = false;
    while(!done)
    {
        if(sum == 11 && checkAce == true)
        {
            computerHand[aceLocation].value = 11;
            done = true;
        }              
        if(sum > 11 && checkAce == true)
        {
            computerHand[aceLocation].value = 1;
            done = true;
        }
        // What if checkAce wasn't true? Infinite loop!
    }
    

    另外,newGame 的前两行没有任何意义:

    void newGame(Card playerHand[], Card computerHand[], Statistics &gameInfo)
    {
        playerHand = '\0';
        computerHand = '\0';
        // ...
    }
    

    数组参数被编译器静默地重写为指针参数。所以你所做的就是将空指针分配给那些本地指针。可能不是你想要的......

    【讨论】:

    • 感谢您的更正.. 在我上次编辑后不需要 while 循环.. 至于第二期,我正在考虑清除数组,这样我就不会从上一场比赛中得到剩余的卡片,但我想那是不需要的,因为我使用统计结构中的 playerCardCount 控制打印..
    【解决方案3】:

    如果你懒得运行调试器,并打算使用 cout

    ( cout << "I am here and going to hang" ).flush() ;
    

    否则,您将看不到最近的输出,因为它仍在输出缓冲区中。试试这个,你很可能会看到什么调用会挂起你的程序。

    【讨论】:

    • 上面没有用到的地方除外:cout &lt;&lt; "Your cards are ";
    • 我尝试过在 cout 声明之前包含它.. 似乎没有任何好处..
    【解决方案4】:

    使以下语句无效

    dealExtra(playerHand, deck, gameInfo);
    printHand(playerHand, gameInfo.playerCardCount);
    

    并检查它是否有效,然后尝试交替激活上述语句之一以找出流在哪个函数中丢失。以此类推。

    【讨论】:

      猜你喜欢
      • 2020-06-08
      • 1970-01-01
      • 2016-02-19
      • 2017-04-04
      • 2016-07-23
      • 1970-01-01
      • 2019-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多