流的内容和字符串`str()`之间的区别是否返回?

时间:2013-12-09 15:01:17

标签: c++ string stringstream

我正在使用生成PDF文件的a small piece of code,这是我在互联网上找到的,并尝试(轻柔地)优化它,因为创建文件需要很长时间。在分析之后,我将其缩小到以下代码:

std::ostringstream tmp;
tmp << std::hex << std::uppercase << std::setfill('0') <<
    std::setw(2) << r << " " <<
    std::setw(2) << g << " " <<
    std::setw(2) << b;

out << tmp.str();

在紧密循环中找到,outostringstream,基本上包含整个PDF内容,然后才会将其写入文件。我发现tmp.str()是在该循环中花费最多时间的行,并且在查找C ++引用时看到str()将返回流的基础字符串的副本。

然后,我想删除该副本并直接使用out会更快。所以我抛弃tmp直接做了:

out << std::hex << std::uppercase << std::setfill('0') <<
    std::setw(2) << r << " " <<
    std::setw(2) << g << " " <<
    std::setw(2) << b;

但现在,生成的PDF文件被视为“已损坏”,无法通过PDF阅读器打开,而前一个可能是。我使用两种方法创建了一个PDF(使用tmp流而没有)来比较行输出,但没有发现明显的差异......

然后,这可能是什么原因?是否有理由使用该临时流?是的,为什么它可能与直接使用out流不同?

我认为它可能与换行符或操纵者有关,但在这些上找不到任何重要的东西

2 个答案:

答案 0 :(得分:10)

要考虑的是io操纵器(例如std::hex)从流上的那一点开始是持久的。

因此,一旦插入std::hex操纵器,从此时开始,所有积分值都以十六进制格式打印出来。

由于操纵器处于瞬态流,因此您之前的方法没有出现此问题。完成后,您可以尝试插入std::dec操纵器...

从Jan Hudec的评论中提出,Boost IO State Savers是处理这个问题的好方法。

答案 1 :(得分:2)

另一个小区别:如果格式化输出到std :: ostringstream失败,则目标输出不受影响。

(Nim的回答描述了实际问题)