3

Cでこれを行う方法は知っていますが、C++ソリューションについてはわかりません。以下をフェイルセーフにしたいのですが、入力に文字列または文字を提供した後、プログラムがハングします。\n を含む入力ストリームを読み取って解放する方法は?

int main() {
    int num;
    do { 
        std::cin.clear();
        std::cin >> num;
        while ( std::cin.get() != '\n' );
    } while ( !std::cin.good() || num > 5 );
    return 0;
}
4

5 に答える 5

2

ストリームがエラー状態になると、すべての読み取り操作が失敗します。これは、cin >> num読み取りが失敗した場合、呼び出しのループがget()終了しないことを意味します。これらすべてのget()s が失敗します。行末へのスキップは、エラー状態をクリアした後にのみ実行できます。

于 2012-12-20T10:36:37.130 に答える
1

R. Martinho Fernandes の回答の上に構築するには、コードに代わる可能な C++ の代替案を次に示します。

std::string num;
std::getline(std::cin, num);

// Arbitrary logic, e.g.: remove non digit characters from num
num.erase(std::remove_if(num.begin(), num.end(),
            std::not1(std::ptr_fun((int(*)(int))std::isdigit))), num.end());

std::stringstream ss(num);
ss >> n;
  • このstd::getline関数は から文字を抽出しcin、 に格納しnumます。また、入力の末尾にある区切り文字を抽出して破棄します (独自の区切り文字を指定すること\nも、使用することもできます)。
  • この関数は、負の述語を使用してstring::erase、文字列から数字以外のすべての文字を削除します。numstd::remove_ifstd::isdigit
  • 次に、文字列は a を使用して整数として表されますstd::stringstream(aboost::lexical_castも同様に機能します)。

ここで消去関数によって実装されるロジックは他のロジックでもかまいませんが、このコードはおそらく質問に含まれているものよりもはるかに読みやすいです。

于 2012-12-20T11:44:27.883 に答える
0

入力ストリームをクリアするには、 cin.sync() を使用します。cin.clear() または cin.ignore() を使用する必要はありません。

于 2016-05-10T20:31:02.110 に答える
0

getline(cin,num) を使用してアプローチし、cin.fail() を使用して失敗をキャッチします。私は通常、 int で cin.fail() を使用しますが、理論的には文字列と文字でも動作するはずです。たとえば、次のようになります。

    string num;
    getline(cin,num);
    if(cin.fail())
    {
      cin.clear();
      cin.ignore();
    }
于 2012-12-20T12:07:10.307 に答える
0

1 つの方法は、すべての入力後に状態をチェックし、それが発生した場合に例外をスローすることです。次に例を示します。

#include<iostream>
using namespace std;

int main(){

int a;
cout<<"Enter a number: ";
cin>>a;

//If a non number is entered, the stream goes into a fail state
try
{
    if(cin.fail()){
        throw 0;
        cin.clear();
        cin.ignore();
    }
}
catch(int){
    cin.clear();
    cin.ignore();
}
return 0;
}

その後、任意のコードを続行できます

于 2014-11-23T20:45:25.397 に答える