文字列ストリームをリセットする


86

文字列ストリームの状態を、作成したときの状態に「リセット」するにはどうすればよいですか?

int firstValue = 1;
int secondValue = 2;

std::wstringstream ss;

ss << "Hello: " << firstValue;

std::wstring firstText(ss.str());

//print the value of firstText here


//How do I "reset" the stringstream here?
//I would like it behave as if I had created
// stringstream ss2 and used it below.


ss << "Bye: " << secondValue;

std::wstring secondText(ss.str());

//print the value of secondText here

回答:


135

これは私が通常行う方法です:

ss.str("");
ss.clear(); // Clear state flags.

ありがとう; 他の誰かのC ++をデバッグし、.clear()メソッドを実行しなかったために発生したアクセス違反エラーを整理するためにこれが必要でした。Intelボックスでは問題なく動作しましたが、AMDマシンでは毎回突かれました。
クリスタウンゼント

3
残念ながら、clearioマニピュレータはリセットされません。テストの失敗例:std :: stringstream ss; ss << "Hello" << std :: setw(15)<< "World" << std :: setw(15); リセット(ss); ss << "Hello World"; assert( "Hello World" == buf.str()); //失敗し、最後のstd :: setwを取得
GameSalutes

9

私はします

std::wstringstream temp;
ss.swap(temp);

編集:christianparpartとNemoによって報告されたエラーを修正しました。ありがとう。

PS:上記のコードは、スタック上に新しいstringstreamオブジェクトを作成し、すべてをss新しいオブジェクト内のオブジェクトと交換します。

利点:

  1. これによりss、新しい状態になることが保証されます。
  2. 新しいオブジェクトはインラインおよびスタック上に作成されるため、コンパイラーはコードを簡単に最適化できます。最後に、すべてのss内部データを初期状態にリセットするようなものになります。

もっと:

  1. 代入演算子との比較:新しいオブジェクトのヒープにバッファが割り当てられている場合、STLスワップメソッドは代入演算子よりも高速になる可能性があります。このような場合、代入演算子は新しいオブジェクトにバッファを割り当てる必要があり、次に古いオブジェクトに別のバッファを割り当ててから、新しいオブジェクトのバッファから古いオブジェクトの新しいバッファにデータをコピーする必要がある場合があります。たとえば、バッファのポインタをスワップするだけの高速スワップを実装するのは非常に簡単です。

  2. C ++ 11。修正は可能ですが、スワップよりも遅いムーブ代入演算子の実装を見てきましたが、おそらくSTL開発者は、移動されたオブジェクトに大量のデータを残したくないでしょう。

  3. std::move()移動したオブジェクトが空になることを保証するものではありません。return std::move(m_container);m_containerをクリアしません。だからあなたはしなければならないでしょう

    自動to_return(std :: move(m_container)); m_container.clear(); to_returnに戻る;

これより良いことはできません

auto to_return;
m_container.swap(to_return);
return to_return;

後者はバッファをコピーしないことを保証するからです。

だから私はswap()それが収まる限り常に好む。


2
なぜこれを行うのを説明する必要があります。このコード自体はそれほど有用ではありません。
–Machavity

1
この答えは正しいかもしれませんが、いくつかの説明を追加してください。基盤となるロジックを与えることは、コードを与えることよりも重要です。これは、OPや他の読者が、この問題や同様の問題を自分で修正するのに役立つためです。
codeMouse92 2015年

私はその解決策が好きです。これは非常に短く、同じテンプレートが実質的にすべてのstdデータ型で機能します。
martinus 2016年

1
一時変数にバインドできない可能性があるため、この答えは完全には正しくありません。つまり、一時変数を作成して、新しく(一時的に)作成された空の文字列ストリームを既存の「ss」ストリームと交換します。禁止されている。
christianparpart 2016

これにより、ロケールを構築するためのすべてのオーバーヘッドが発生しませんか?これは、文字列ストリームをリセットすることで回避できるはずです。
2016年

2

上記の答えに基づいて、フォーマットもリセットする必要があります。全体として、新しいstd :: stringstreamインスタンスが構築されるときに、バッファの内容、ストリーム状態フラグ、およびフォーマットをデフォルトにリセットしています。

void reset(std::strinstream& stream)
{
    const static std::stringstream initial;

    stream.str(std::string());
    stream.clear();
    stream.copyfmt(initial);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.