web-dev-qa-db-ja.com

文字列ストリームを再利用する方法

これらのスレッドは私に答えません:

文字列ストリームのリセット

stringstream変数をどのようにクリアしますか?

        std::ifstream file( szFIleName_p );
        if( !file ) return false;

        // create a string stream for parsing

        std::stringstream szBuffer;

        std::string szLine;     // current line
        std::string szKeyWord;  // first Word on the line identifying what data it contains

while( !file.eof()){

            // read line by line

            std::getline(file, szLine);

            // ignore empty lines

            if(szLine == "") continue;

            szBuffer.str("");
            szBuffer.str(szLine);
            szBuffer>>szKeyWord;

szKeywordには常に最初のWordが含まれます。szBufferはリセットされておらず、stringstreamの使用方法に関する明確な例を見つけることができません。

回答後の新しいコード:

...
            szBuffer.str(szLine);
            szBuffer.clear();
            szBuffer>>szKeyWord;
...

OK、それが私の最終バージョンです。

        std::string szLine;     // current line
        std::string szKeyWord;  // first Word on the line identifying what data it contains

        // read line by line

        while( std::getline(file, szLine) ){

            // ignore empty lines

            if(szLine == "") continue;

            // create a string stream for parsing

            std::istringstream szBuffer(szLine);
            szBuffer>>szKeyWord;
17
Icebone1000

clear()を呼び出した後、ストリームをstr("")していません。 この答え をもう一度見てください。また、str(std::string())を使用してリセットする必要がある理由も説明しています。また、あなたの場合、str(szLine)のみを使用して内容をリセットすることもできます。

clear()を呼び出さない場合、ストリームのフラグ(eofなど)はリセットされず、予期しない動作が発生します;)

30
Marcus Riemer

それはあなたがそれで何をしているかに依存します。一般に、新しいistringstreamまたはostringstreamを作成する方が簡単です。ストリームを「リセット」するには、バッファをクリアし、エラーフラグをクリアし、フォーマットフラグをリセットして、精度と塗りつぶしを元のロケールでre imbue再設定し、生成された拡張フォーマット情報を忘れないようにする必要があります。 xallocから返された値を使用します。要するに、正解することは不可能です。

そして、私がそうしている間、あなたのループは間違っており、おそらく最後の行が2回処理される結果になります。 file.eof()は、入力が失敗した後にのみ使用可能な意味を持ちます(それでも、100%信頼できるわけではありません)。あなたが欲しいのは:

std::string line;
while ( std::getline( file, line ) ) {
    if ( !line.empty() ) {
        std::istringstream buffer( line );
        //  ...
    }
}

(実際には、空のテストの前に、行の末尾の空白を削除する必要があります。)

8
James Kanze

ほとんどの場合、同じものをリセットする代わりに、新しいistringstreamまたはostringstreamを作成する方が簡単です。

ただし、再送信したい場合は、次のようにします。

  • (予期しない動作を回避するために)clear ()を使用してストリームのフラグを再送信します。

  • stringstreamの内容はstr ("")を使用して修正できますが、効率を上げるためにstr(std::string())を使用することをお勧めします。

1
Madhav Datt

クラスメンバーにストリームがある場合は、_unique_ptr<stringstream>_を使用してから、reset(new stringstream(...))を使用して再利用します。

ssはstringstreamです。使用する

  • 最初のステップ:ss.clear();
  • 2番目のステップ:ss.str( "");

文字列ストリームを再利用します-文字列ストリームを完全にクリアします。

0
user5732391

構成ファイルを想像してください。

par1=11
par2=22

コード:

std::string line, strpar1, strpar2;
int par1, par2;
std::ifstream configfile("config.cfg");

std::getline(configfile, line);    // first line to variable "line"
std::istringstream sline(line);
while (std::getline(sline, strpar1, '='));
par1 = std::stoi(strpar1);  // par1 get 11

bool b = sline.eof(); // true

std::getline(configfile, line);    // second line to variable "line"
sline.clear();    //
sline.str(line);    // reuse "sline"

b = sline.good();  // true  // goodbit is zero, indicating that none of the other bits is set.
b = sine.fail();  // false
b = sline.bad();  // false
b = sline.eof(); // false

while (std::getline(sline, strpar2, '='));
par2 = std::stoi(strpar2);  // par2 get 22

goodbitはゼロで、他のどのビットも設定されていないことを示します

0
Nick Dong