2

Python コンソール / irb の動作に似た、対話型シェルを実装するアプリケーションがあります。問題は、ユーザーが誤って^DEOF を発行し、私のgetline()呼び出しが空の文字列を返し、それを「入力なし」として扱い、プロンプトを再度表示した場合です。

これにより、プロンプトを出力する無限ループが発生します。

Python では をキャッチすることでその問題を解決しますが、C++ ではキャッチできる例外は発生せず、 EOF を無視するEOFError設定もないようです。cin

ヒントはありますか?

4

5 に答える 5

7

何も読み取れなかった場合は、を設定しfailbitます。if条件でストリームをテストし、ビットをクリアするだけです。

if(!getline(std::cin, myline)) {
    std::cin.clear();
    std::cout << "you should enter something" << std::endl;
}

内部的には、シーケンスは次のようになります。

  • ターミナルで文字列を待ちます。ユーザーが改行を送信するまで、ターミナルはブロックされます。考えられる2つのエラーケース
    1. ユーザーはすぐにEOFを押します。これによりgetline、何も読み取られなくなり、とが設定されfailbitますeofbit
    2. ユーザーが何かを入力してからEOFを押します。これにより、getline何かが消費され、次の文字を取得しようとしているときにEOFにヒットします。これeofbitが設定されます。
  • もう一度何かを読み込もうとします。istream::sentry抽出関数は、ストリームがどのような状態であるかをチェックするタイプのオブジェクトを作成します。エラービットのいずれかが設定されている場合、抽出関数はすぐに戻ります。それは前に無限のループを引き起こしました。

を呼び出すと、clear()すべてのエラービットがクリアされ、もう一度読み続けることができます。

于 2009-03-23T17:37:27.680 に答える
3

litbのおかげで正しい解決策:

if (!getline(std::cin, str)) {
    std::cin.clear();
    std::cout << std::endl;
}
于 2009-03-23T17:51:19.300 に答える
1

このgetline()関数は、次のビットを使用してエラーを通知します。

  • eofbit
  • フェイルビット
  • バッドビット

先に進む前に、これらを確認してみてください。

于 2009-03-23T17:35:51.083 に答える
0

http://www.horstmann.com/cpp/pitfalls.htmlを参照してください

次のようなコードを使用できます。

while (cin)
{  int x;
   cin >> x;
   if (cin) a.push_back(x);
}
于 2009-03-23T17:40:41.137 に答える
0

わかりました、他の回答では、cin.clear()を使用することが可能な解決策として説明されました。

もう1つのトリックは、ターミナルを別のモードに設定してCtrl + Dを直接処理できるようにすることで、通常の標準とは別の方法でコンソールからの入力を処理することです。RAWモードなどでは、ユーザー側から入力および制御シーケンスに直接アクセスでき(Ctrl+DやCtrl+Cなど)、他の場所では処理されなくなります。

より多くの情報を収集しようとする(またはコーディング時間を節約する)ライブラリもあります。

½ここのドキュメントで問題に関する情報を見つけることができます。

于 2009-03-23T17:41:00.277 に答える