2009-03-08 12 views
111

ostringstream(と基になるバッファ)をクリアして再利用したいので、私のアプリが多くの割り当てを行う必要はありません。オブジェクトを初期状態にリセットするにはどうすればよいですか?ストリングストリームを再利用するには?

+0

可能重複http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream -variable) – mpromonet

答えて

145

私が過去に明らかとstrのシーケンスを使用しました:

入力と出力の両方stringstreamsのための事を行っている
// clear, because eof or other bits may be still set. 
s.clear(); 
s.str(""); 

。代わりに、現在の出力バッファにあるものは何でも上書きすることによってstrによって行われ、いくつかの再配分を防ぐことができます

s.clear(); 
s.seekp(0); // for outputs: seek put ptr to start 
s.seekg(0); // for inputs: seek get ptr to start 

:また、手動でクリアな、そして開始に適切なシーケンスを求めることができます。結果はこのようなものです:あなたは、C-機能のための文字列を使用したい場合は

std::ostringstream s; 
s << "hello"; 
s.seekp(0); 
s << "b"; 
assert(s.str() == "bello"); 

、あなたはこのように終端ヌルを入れ、std::endsを使用することができます。

std::ostringstream s; 
s << "hello"; 
s.seekp(0); 
s << "b" << std::ends; 
assert(s.str().size() == 5 && std::strlen(s.str().data()) == 1); 

std::endsは非推奨の遺存ですstd::strstreamは、スタックに割り当てたchar配列に直接書き込むことができました。手動で終端するNULLを挿入する必要がありました。しかし、std::endsは廃止されたものではありません。なぜなら、上記のように有用であるからです。

+0

ostreamでs.str()を使用しようとしています。サイズはそれを台無しにしている(私は最初の文字がnullであることがわかりますが、それはもっと多くを印刷します)。 strの長さを修正する良い方法はありますか?私はs.str()を使用しています。 ATMとそれはうまく動作します –

+0

実際には、これは正しくないです。私はちょうど 's.str(" ");を代わりにしました。 'auto str = s.str();自動cstr = str.c_str();ファイル<< cstr; s.clear(); s。seekp(0); s << ends; ' –

+0

std :: endsはgoogleテストでは動作しません ' boost :: any a = 1; std :: ostringstreamバッファ。 バッファ<< << std :: ends; EXPECT_EQ(buffer.str()、 "任意の<(int)1>"); ' ' TestUtilsTest.cpp:27:失敗 が予想される:buffer.str() がある: "任意の<(int)1> \ 0" はに等しくなるように: "任意<(int)1>" と私は別の長さの文字列を使用して再利用する場合、私は少し残って取得 –

5

ostr.str("")コールがトリックを行うように見えます。

+8

これはostringstreamからの基底のバッファーを再使用しないことを指摘しています - 単に新しいバッファーを割り当てます。だから、オブジェクトを再利用している間は、まだ2つのバッファを割り当てています。私はostringstreamが意図したやり方で再利用できるように設計されているとは思わない。 – razlebe

+2

また、状態をクリアしません。これは.clear()が行うことです。私は同意する、それは本当にこのように使用するつもりはない。確かに新しいものを作成してください。あなたがプロフィールを作成した場合にのみ、違いがあるかどうかを知ることができます。 –

+1

sgreeve、Brian、そうです。しかし、上記のlitbのメソッドがstd :: endsの使い方をどのように必要としているかに注意してください。バッファーを再利用しますが、通常はストリングストリームでコードを違うようにします(通常、std :: endsは使用しません)。 –

0

あなたはそうではありません。明確にするために2つの異なる名前のストリームを使用し、最適化コンパイラが古いものを再利用できることを理解させる。

+6

...もちろん、そうであることを願っています。 –

+4

は、コードが入力データをループし、 'ostringstream'(データ読み込みに基づいて)に書き込んだり、' ostringstream'で構築された文字列を時々どこかに書き込まなければならないというユースケースを考えています文字列が読み込まれました)、新しい文字列の作成を開始します。 –

2

最初に使用する前にバッファをクリアする方法でバッファをクリアする場合は、バッファに最初にMSVCを追加する必要があります。

struct Foo { 
    std::ostringstream d_str; 
    Foo() { 
     d_str << std::ends; // Add this 
    } 
    void StrFunc(const char *); 
    template<class T> 
    inline void StrIt(const T &value) { 
     d_str.clear(); 
     d_str.seekp(0); // Or else you'll get an error with this seek 
     d_str << value << std::ends; 
     StrFunc(d_str.str().c_str()); // And your string will be empty 
    } 
}; 
[C++では、どのようにstringstream変数をクリアしますか?](の
+0

私はVS2012で失敗した動作を見ていません。さらに、 '' clear'(http://www.cplusplus.com/reference/ios/ios/clear/)を呼び出すと、ストリームが空の場合にセットされる 'failbit'が_causeされます。 ['seekp'](http://www.cplusplus.com/reference/ostream/ostream/seekp/)を呼び出すだけで、ストリームが存在しなければ単純に戻ります。 –