0

stringstreamstringstream::ignore()を呼び出した後にこれが行われたとしても、を呼び出すと常に失敗するようですstringstream::clear():

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cassert>

using namespace std;

int main() {
    int a, b;
    stringstream ss;
    string str;
    ifstream inFile("file.txt");
    if(!inFile) {
        cerr << "Fatal: Cannot open input file." << endl;
        exit(1);
    }

    while(getline(inFile, str)) {
        ss << str;                // read string into ss
        ss >> a >> b;             // stream fails trying to store string into int

        ss.clear();               // reset stream state
        assert(ss.good());        // assertion succeeds

        ss.ignore(INT_MAX, '\n'); // ignore content to next newline
        assert(ss.good());        // assertion fails, why?
    }

    return 0;
}

file.txt次のテキストが含まれています。

123 abc
456 def

ss.good()の後に falseがあるのはなぜss.ignore()ですか?

4

2 に答える 2

1

std::endlストリームを出力\nしてフラッシュします。ただし、stringstream::flush()意味がなく、何もしません。flush基になるバッファが端末などの出力デバイスに関連付けられている場合にのみ意味がありますが、astringstreamには内容をフラッシュする場所がありません。文字列ストリームの内容をクリアしたい場合は、ss.str("");代わりに行ってください。ただし、おそらくコードを次のように変更します。

while(getline(inFile, str)) {
    ss.str(str);              // call ss.str() to assign a new string to the stringstream
    if(!ss >> a >> b)         // check if stream fails trying to store string into int
    {
        ss.clear();           // Read failed, so reset stream state
    }
    else
    {
        // Read successful
    }
    // Do other stuff
}

また、文字列ストリームに改行を挿入する場合は、をss << '\n';呼び出すだけで、呼び出さないでくださいstd::endl

于 2012-09-22T07:21:41.413 に答える
0

の最後に改行がないことがわかりましたss。次のステートメントを実行した後:

getline(infile, str);
ss << str;

ssgetline()は、2 番目のパラメーターに格納された文字列の末尾に改行文字を追加しないため、改行文字を含みません。その結果、このステートメントが実行されると、次のようになります。

ss.ignore(INT_MAX, '\n');

停止する改行文字が見つからずにストリームの終わりに到達したため、ストリームは失敗します。


ss.ignore()を使用して文字列を格納する場合は必要ありませんss.str()。これにより、ストリームの内容全体が置き換えられます。 ストリームが失敗した場合は、ストリームをリセットし、その内容を空の string に設定する必要があります""。代わりにss.ignore()使用できますが、ストリームが失敗しないように、データが読み取られた直後に改行文字がストリームに挿入されている場合に限りますが、ストリームの内容が後で設定される場合、これは冗長になります。を使用して別の値に変更しss.str()ます。

ファイルの次の行の正常な読み取りはss.clear()、ストリームにファイルの次の行の内容が割り当てられる前に を呼び出すことによって保証できます。これは、ストリームの古い内容が で上書きされるためss.str()です。ストリームの状態はループの開始時にリセットでき、ループの後半でストリームが失敗しても問題は発生しません。

while(getline(inFile, str)) {
    ss.clear();   // make sure stream is good
    ss.str(str);  // overwrite contents of stream with str
    ss >> a >> b;
    // Even if the stream fails after this line, the stream is reset before each
    // line is stored into the stream, and no problems should occur while reading
    // and parsing subsequent lines in the file.

    // Code to validate and store data from file...
}
于 2012-09-22T05:36:56.377 に答える