4

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

整数が必要なときに文字を入力すると、私のループは無限に繰り返され、その逆も同様です。

#include<iostream>

int main()
{
    while (cout << "Enter a number" && !(cin >> num)) 
    {
        cin.sync(); 
        cin.clear();
        cout << "Invalid input; please re-enter.\n";
    }
}

プログラムが新しい入力を再度求めるようにするにはどうすればよいですか?

4

3 に答える 3

5

失敗した場合cin >> num、無効な入力をストリームから削除する必要があります。これを達成するためignoreに代わりに使用することをお勧めします。syncその理由はsync、標準ライブラリのすべての実装で残りの入力を削除することが保証されていないためです。

#include <iostream>
#include <limits>

int main()
{
    int num;
    while (cout << "Enter a number" && !(cin >> num)) 
    {
        cin.clear();    // clear the error

        // Remove input up to a new line
        cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
        cout << "Invalid input; please re-enter.\n";
    }
}

上記の使用例はstd::numeric_limits<std::streamsize>::max()、入力バッファーが保持できる最大文字数を取得するために使用されます。これによりignore()、新しい行まで可能な限り多くの文字を削除できます。これは慣用的な C++ であり、現在抱えている問題を隠すだけのマジック ナンバーを使用するよりも好まれます。

これはうまく機能しますが、入力の数字の後に余分な文字が含まれている状況を処理しません。このような状況に対処するには、追加の検証を処理するためにループを少し変更する必要があります。1 つのオプションは、 から行全体を読み取り、cinそれを に配置し、std::stringstreamそこから数値を読み取り、追加の検証を行うことです。ただし、考慮する必要がある特殊なケースが 1 つあります。数字の後の文字が空白のみである行です。幸いなことに、標準ライブラリにはstd::skipws、状況を簡単に処理できるストリーム修飾子が用意されています。以下の例は、あまり手間をかけずにこれを行う方法を示しています

#include <iostream>
#include <sstream>

int main()
{
    int num;

    for(;;)
    {
        std::cout << "Enter a number: " << std::flush;

        std::string line;
        std::getline(std::cin, line); // Read a line from console
        std::stringstream text(line); // store in a string stream

        char ch = 0;
        if(!(text >> num).fail() && (text >> std::skipws >> ch).fail())
        {
            break;
        }

        std::cout << "Invalid input; please re-enter.\n";
    }

    return 0;
}

この式(text >> std::skipws >> ch).fail()は、数字の後に表示されるすべての空白をスキップしてから、1 文字を読み取ろうとします。使用可能な文字がない場合、読み取りは失敗し、ユーザーが数字のみを入力したことを示します。これを実行しようとするとcin、入力が有効であっても、ユーザーがさらにテキストを入力するのを待つことになります。

于 2013-05-29T15:00:40.260 に答える
-1

入力を文字列として読み取り、整数に変換して検証することができます..

#include <iostream>
#include <string>
using namespace std;
int main()
{
    int number = 0;
    string input;
    do {
        cout << "Enter a number: ";
        cin >> input;
        number = atoi(input.c_str()); // atoi returns 0 on error..
        if (number != 0 || input.compare("0") == 0) // but maybe the user really entered "0".
            break;
        cout << endl;
        cout << "Invalid input; please re-enter.\n";
    } while (1);
    cout << "You entered " << number << endl;
    return 0;
}

サンプル プログラムの実行:

% ./foo
Enter a number: abc

Invalid input; please re-enter.
Enter a number: 2
You entered 2
% ./foo
Enter a number: 0
You entered 0

.. ただし、これはおそらく最もエレガントなソリューションではありません。

于 2013-05-29T14:56:23.580 に答える