iostream系は引数が覚えにくいという理由で使ってません。
しかし、気まぐれで使ったstringstreamでちょっとした衝撃を受けました。簡易再現コードは以下の通り。

int i;
double d;
stringstream sstr;
sstr << &quot;10.25&quot;;
sstr << &quot;10.50&quot;;
sstr >> i;
sstr >> d;

個人的に期待した動作はi=10、d=10.5でしたが・・・


d=0.25になりました。
つまり、最初の文字列の10.25のうち、”10”だけがクリアされて、次の”.25”がdに入ってしまったのです。元のコードはもっと複雑だったため、10分くらい考え込んでしまいました。
この動作はVC++7.1と8.0で確認しています。現在手元に無いため、C++仕様書は確認していませんが、結果をみた後からなら納得できた仕様なので、たぶん仕様でしょう。
しかし罠だよなぁ・・・これ。

  4 コメント

  1. d は 0.251 になりませんか?g++ だとそうなりますが。

  2. コメント有り難うございます。
    正しくは0.251である事を再確認しました。(VC++8)
    当時の事は忘れてしまいましたが、混ぜるな危険ということを言いたかったのだと思います。尚、入力は下記にすれば分かりやすかったなと反省しました。
    sstr << "12.34";
    sstr << "56.78";
    この場合の出力はi=12, d=0.3456となります。

  3. "12.34" と "56.78"が連結され、
    "12.3456.78" になった後、
    int は小数点を含まないので "12" が読み込まれ、
    double は小数点を含むので".3456" が読み込まれます。

  4. > "12.3456.78" になった後、
    演算子 '<<' が 単なる文字列追加であるのは仕方ないとして、2回目の出力が「0.3456」であるのか、「3456.78」であるか、直感的に分からないのが何とも・・・。

 返信する

以下のHTML タグと属性が利用できます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">

Spam Protection by WP-SpamFree

   
© 2011 二流プログラマの三流な日常 Suffusion theme by Sayontan Sinha