0

ストリームの動作について質問があります。次の例を参照してください。私が期待していたのは、文字列に 5 文字しかないため、10 文字を読み取ろうとするとストリームの読み取りが停止することです。代わりに、出力は「hellooooo」です...最後の文字が繰り返されます。私の質問は 2 つあります。まず、なぜですか。第二に、最後の文字を繰り返さないようにストリームを動作させる方法はありますか?

#include <sstream>
#include <iostream>
using namespace std;

int main(void) {
    char c;
    string msg("hello");
    istringstream iss(msg);
    unsigned int i = 0;
    while (i < 10) {
        iss >> c;
        cout << c;
        i++;
    }
    cout << endl;
    return 0;
}
4

3 に答える 3

2

表示されるのは、誤った状態でストリームから読み取った結果です。ストリームの最後の要素 (これは文字列ストリーム) を超えて読み取ると、ストリームはエラーになり、それ以外の読み取りの試みは失敗します (抽出変数はそのまま残ります)。

さらに読む前に、抽出操作が成功したかどうかを確認する必要があります。

if (iss >> c) {
  // succeess
} else {
  // failed to extract, handle error
}

コンソールに接続されたストリームを使用した場合 (たとえば)、 への呼び出し>>は期待どおりにブロックされます。の動作stringstreamは異なります (奇跡的により多くのデータを含めることは期待できません)。

于 2012-06-20T18:17:24.177 に答える
0

「最後の文字が繰り返される」失敗した場合、
変更されません。iss >> cc

if (iss >> c)この式:を直接評価して、値の抽出が成功したかどうかを確認しますが、 を呼び出すことさえ考えないiss.good()でください。この回答を確認し、以下もご覧ください:
How does that funky while (std::cin >> foo) syntax work?
入力がファイルの終わりを超えて処理されているように見えるのはなぜですか?

于 2012-06-20T18:21:09.990 に答える
0

その理由は、ストリームの最後まで読み取った場合、それ以降の読み取りの試みはすべて失敗し、最後に読み取られた値が に残るためcです。

最大10 文字を読みたい場合:

while (i < 10 && is >> c) {
    cout << c;
    i++;
}

これが機能するのは、ストリームを に変換できるためです。これbooltrue、ストリームが「良好な」状態にある場合です。

于 2012-06-20T18:18:30.817 に答える