web-dev-qa-db-ja.com

間違ったデータ型の入力を処理する方法

C++では、間違った入力をどのように処理しますか?同様に、プログラムが整数を要求する場合、文字を入力するときに何かを実行してから入力を繰り返すことができるはずですが、整数が必要なときに文字を入力するとループが無限になります。

22
Zik

プログラムが無限ループに入る理由は、入力の失敗によりstd::cinの不正な入力フラグが設定されているためです。すべきことは、そのフラグをクリアし、入力バッファからの不正な入力を破棄することです。

//executes loop if the input fails (e.g., no characters were read)
while (std::cout << "Enter a number" && !(std::cin >> num)) {
    std::cin.clear(); //clear bad input flag
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard input
    std::cout << "Invalid input; please re-enter.\n";
}

C++ FAQ を参照してください。条件に最小値や最大値を追加するなど、他の例もご覧ください。

別の方法は、入力を文字列として取得し、std::stoiまたは変換をチェックできる他のメソッドを使用して整数に変換することです。

44
chris

上位の回答は、ソリューションを非常によくカバーしています。

その答えに加えて、これは何が起こっているかを少し良く視覚化するのに役立ちます。

_int main()

    int input = 1;//set to 1 for illustrative purposes
    bool cinState = false;
    string test = "\0";
    while(input != -1){//enter -1 to exit
        cout << "Please input (a) character(s): ";//input a character here as a test
        cin >> input; //attempting to input a character to an int variable will cause cin to fail
        cout << "input: " << input << endl;//input has changed from 1 to 0
        cinState = cin;//cin is in bad state, returns false
        cout << "cinState: " << cinState << endl;
        cin.clear();//bad state flag cleared
        cinState = cin;//cin now returns true and will input to a variable
        cout << "cinState: " << cinState << endl;
        cout << "Please enter character(s): ";
        cin >> test;//remaining text in buffer is dumped here. cin will not pause if there is any text left in the buffer.
        cout << "test: " << test << endl;
    }
    return 0;    
}
_

バッファー内のテキストを変数にダンプすることは特に有用ではありませんが、cin.ignore()が必要な理由を視覚化するのに役立ちます。

whileループまたはswitchステートメントの条件で入力変数を使用している場合、デッドロック状態になるか、または条件を満たしている可能性があるため、入力変数への変更にも注意しました。期待することはできませんが、デバッグするのがより複雑になる可能性があります。

6
AWolfAtTheDoor