問題はそれです:
cin >> input;
数値以外の値を読み取ろうとすると、不良ビットが設定されます。その後、 を使用しようとしてもoperator>>
黙って無視されます。
したがって、これを修正する方法は、ストリームが良好な状態にあるかどうかをテストし、そうでない場合は状態フラグをリセットして、もう一度読み取りを試みることです。ただし、(問題の原因となった) 不良な入力がまだ入力にあることに注意してください。
if (cin >> input)
{
// It worked (input is now in a good state)
}
else
{
// input is in a bad state.
// So first clear the state.
cin.clear();
// Now you must get rid of the bad input.
// Personally I would just ignore the rest of the line
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// now that you have reset the stream you can go back and try and read again.
}
(不良ビットが設定されていることが原因で) スタックするのを防ぐには、文字列に読み取ってから、文字列ストリームを使用してユーザー入力を解析します。また、さまざまなスタイルの読み取りを簡単に組み合わせることができるため (つまり、組み合わせて、文字列ストリームでこれらを使用できるため)、この方法 (ユーザーの対話型入力用) を好みoperator>>
ますstd::getline()
。
#include <iostream>
#include <sstream>
#include <string>
// using namespace std;
// Try to stop using this.
// For anything other than a toy program it becomes a problem.
int main(int argc, char *argv[])
{
int input;
std::string line;
while(std::getline(std::cin, line)) // read a line at a time for parsing.
{
std::stringstream linestream(line);
if (!(linestream >> input))
{
// input was not a number
// Error message and try again
continue;
}
if ((input < 1) || (input > 3))
{
// Error out of range
// Message and try again
continue;
}
char errorTest;
if (linestream >> errorTest)
{
// There was extra stuff on the same line.
// ie sobody typed 2x<enter>
// Error Message;
continue;
}
// it worked perfectly.
// The value is now in input.
// So break out of the loop.
break;
}
}