SSブログ

stringstreamのクリア方法 [日記]

stringstreamについて調べていたら、stringstreamのクリアの方法を紹介しているページが沢山見つかりました。

ちなみに、stringstreamクラスは、C言語でのsprintfのC++版というか、Javaや.NETのStringBuilderのC++版というか、色々なデータから文字列を組み立てるためのクラスです。

std::stringstream buff;
buff << "変数の値 = " << n << "\n";

std::string text = buff.str();

こんな感じで使用します。

そして、一旦stringstreamに蓄えたデータを破棄する方法が分かりづらいようです。
と言うか、実際分かりづらい。

stringstreamには、clear()というメンバ関数がありますが、これは、ストリームのエラーフラグをクリアするためのものです。

データをクリアするには、str()を使います。

std::stringstream buff;
buff << "変数の値 = " << n << "\n";

std::string text = buff.str();

buff.str("");    // ← これでクリア

assert(buff.str() == "");

だが、ここで一言、言わせて頂きたい。

stringstreamのデータをクリアしようとする意味が分からん。


stringstreamのデータをクリアしたいと言うことは、とある文字列を組み立てた後、同じstringstreamのインスタンスを再利用して別の文字列を作成するつもりなのでしょうが…

『同じ変数を異なる用途で再利用しない』

と言うのは、分かりやすく安全なコードを書くための鉄則です。

クラスのインスタンスについても同じです。
インスタンスを再利用するのではなく、もう1つ作りましょう。

std::stringstream buff;

buff << "1つ目";
std::string text1 = buff.str();

buff.str("");

buff << "2つ目";
std::string text2 = buff.str();

とするのではなく、

std::stringstream buff4text1;
buff4text1 << "1つ目";
std::string text1 = buff4text1.str();

std::stringstream buff4text2;
buff4text2 << "2つ目";
std::string text2 = buff4text2.str();

stringstreamは文字列を作るための一時的なものと考えるのなら、

std::string text1 = build_text1();
std::string text2 = build_text2();

std::string build_text1()
{
    std::stringstream buff;
    buff << "1つ目";
    return buff.str();
}

std::string build_text2()
{
    std::stringstream buff;
    buff << "2つ目";
    return buff.str();
}

とするのがベターじゃないかな。
状況によっては、関数に引数が必要だったり、インライン関数した方が良かったりするでしょうが。


データをクリアした方が動作が速いのかも知れませんが、(ありとあらゆる最適化を施した後の)一番最後に検討すべきレベルの最適化なので、気にしてはいけません。(多分、それほど処理速度は変わらない)


『オブジェクト指向言語は、オブジェクトを作ってなんぼ』

[バス] 今日の一冊
クラッカーの教科書

クラッカーの教科書

  • 作者: 嶋崎聡
  • 出版社/メーカー: データ・ハウス
  • 発売日: 2009/09/29
  • メディア: 単行本(ソフトカバー)

タグ:C++
nice!(0)  コメント(4)  トラックバック(0) 

nice! 0

コメント 4

名無しさん

std::ostringstreamがメンバだったときはどうするの? と言ってみる。わざわざstd::auto_ptr<std::ostringstream>にするのもねぇ。
by 名無しさん (2012-10-23 23:09) 

晶紀

std::ostringstream をメンバとして持っているクラスのオブジェクトを作り直したら良いんじゃないかな。
by 晶紀 (2012-10-25 20:45) 

sekiwada

上位5つまでのランキングデータを更新したくて
古いデータを上書きしたいのですが
クリア(再利用)しない実装方法はあるでしょうか..

データクリアの難易度高い時点で 普通に使う気が失せるなぁ..
by sekiwada (2019-06-18 17:28) 

晶紀

ランキングのデータにstd::ostringstreamが使われているというイメージがわかないのですが…。
std::vectorとかに insertして6番目以降を削除とかでは無く?
by 晶紀 (2019-06-19 07:46) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。