3

間違ったタイプを入力した場合に、cinステートメントが「削除」されないようにする方法を知る必要があります。コードはここにあります:

int mathOperator()
{
  using namespace std;

  int Input;
  do
  {
    cout << "Choose: ";
    el();
    cout << "1) Addition";
    el();
    cout << "2) Subtraction";
    el();
    cout << "3) Multiplication";
    el();
    cout << "4) Division";
    el();
    el();
    cin >> Input;

  }
  while (Input != 1 && Input != 2 && Input!=3 && Input!=4);
  return Input;
}

たとえば、文字を実行して入力すると、cinステートメントが存在しないかのようにノンストップでループします。

4

6 に答える 6

5

入力が成功したことを確認し、失敗した場合は処理する必要があります。

int mathOperator() {
  using namespace std;

  int Input;
  do {
    cout << "Choose: ";
    el();
    cout << "1) Addition";
    el();
    cout << "2) Subtraction";
    el();
    cout << "3) Multiplication";
    el();
    cout << "4) Division";
    el();
    el();
    while (!(cin >> Input)) {  // failed to extract
      if (cin.eof()) {  // testing eof() *after* failure detected
        throw std::runtime_error("unexpected EOF on stdin");
      }
      cin.clear();  // clear stream state
      cin.ignore(INT_MAX, '\n');  // ignore rest of line
      cout << "Input error.  Try again!\n";
    }
  } while (Input != 1 && Input != 2 && Input!=3 && Input!=4);
  return Input;
}

抽出が成功したことを確認しない場合、cin は失敗した状態 (cin.fail()) のままになります。失敗した状態になると、その後の抽出はストリームから読み取ろうとする代わりにすぐに戻り、実質的に何も操作を行わず、無限ループにつながります。

于 2011-02-01T17:16:58.130 に答える
3

入力が適切な形式であることを確信していない限り、入力ストリームから直接使用することはほとんどありませoperator>>

通常、 で行を読み、std::getlineそれを に入れ、std::istringstreamそこから読む方が簡単です。それが失敗した場合は、エラー メッセージを出力/ログに記録し、残りの行を破棄して (おそらく) 次の行に進みます。

于 2011-02-01T17:16:39.020 に答える
2
char Input;

 do
 {
// same code 
 }
 while (Input != '1' && Input != '2' && Input != '3' && Input!='4');
 return Input;

[編集]

charをintに変換する場合は、このコードを使用できます

int i = (Input - 48);
于 2011-02-01T17:08:35.707 に答える
2

読まないint、読んでchar、cinが無効な文字を渡すようにする

于 2011-02-01T17:09:14.280 に答える
2

不正な値を読み取った後、cinは「失敗」状態になります。これをリセットする必要があります。

エラーフラグをクリアし、バッファを空にする必要があります。したがって:

   cin.clear(); 
   cin.ignore(std::numeric_limits<streamsize>::max(), '\n');

2番目の呼び出しは、そこにある可能性のあるデータの入力バッファーを「フラッシュ」して、次の「cin」呼び出しの準備をします。

これらの2行を「コード全体」に記述していることに気付いた場合は、それを置き換える単純なインライン関数を記述できます。

   inline void reset( std::istream & is )
   {
       is.clear();
       is.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
   }

私はこの関数に任意のistreamを使用させましたが、ほとんどのcin場合、ユーザーが入力して無効なものを入力する場合にのみ使用されます。無効なファイルまたは文字列ストリームの入力である場合、それを修正する方法はありません。例外をスローするのが最善です。

于 2011-02-01T17:11:58.087 に答える
0

いつでもintにキャストできるので、なぜこれが起こっているのかという質問に答えるために、charが同じように便利であることに同意します。ループ中の入力ストリーム。これが「消える」ように見える理由です。

詳細については、成江の投稿 ( http://www.daniweb.com/forums/thread11505.html ) を参照してください。

于 2011-02-01T17:13:21.883 に答える