【问题标题】:resetting a stringstream [duplicate]重置字符串流[重复]
【发布时间】:2011-10-01 23:36:41
【问题描述】:

如何将字符串流的状态“重置”为创建时的状态?

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

【问题讨论】:

    标签: c++ string stringstream


    【解决方案1】:

    这是我通常的做法:

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

    【讨论】:

    • 谢谢;调试其他人的 C++ 并需要它来解决由于没有执行 .clear() 方法而导致的访问冲突错误。在英特尔机器上运行良好,但在 AMD 机器上每次都吐。
    • 不幸的是 clear 不会重置 io 操纵器。示例失败测试:std::stringstream ss; ss
    【解决方案2】:

    我愿意

    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。所以你必须这样做

      auto to_return(std::move(m_container)); m_container.clear(); 返回到_return;

    没有比这更好的了

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

    因为后者保证它不会复制缓冲区。

    所以我总是更喜欢swap(),只要它适合。

    【讨论】:

    • 你应该解释为什么你会这样做。这段代码本身并不是很有用。
    • 虽然这个答案可能是正确的,但请添加一些解释。传递底层逻辑比仅仅提供代码更重要,因为它可以帮助 OP 和其他读者自己解决这个问题和类似问题。
    • 我喜欢这个解决方案。它非常短,而且几乎所有标准数据类型都使用相同的模板。
    • 这个答案并不完全正确,因为您可能不会绑定到临时变量,也就是说,您创建一个临时变量来将新(临时)创建的空字符串流与现有的“ss”交换。不允许。
    • 这不会产生构建语言环境的所有开销,而重置字符串流应该避免吗?
    【解决方案3】:

    在上述答案的基础上,我们还需要重置任何格式。总之,在构造新的 std::stringstream 实例时,我们会将缓冲区内容、流状态标志和任何格式重置为默认值。

    void reset(std::stringstream& stream)
    {
        const static std::stringstream initial;
        
        stream.str(std::string());
        stream.clear();
        stream.copyfmt(initial);
    }
    

    【讨论】:

      猜你喜欢
      • 2015-12-09
      • 2016-12-21
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 2019-04-17
      • 2019-07-04
      相关资源
      最近更新 更多