重置字符串流


86

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

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

Answers:


134

这是我通常这样做的方式:

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

谢谢; 调试其他人的C ++,需要这样做来解决由于未执行.clear()方法而导致的访问冲突错误。在intel盒上工作正常,但每次在AMD机器上都按入。
克里斯·汤森

3
不幸的clear是不会重置io机械手。测试失败的示例:std :: stringstream ss; ss <<“ Hello” << std :: setw(15)<<“ World” << std :: setw(15); 重设; ss <<“ Hello World”; assert(“ Hello World” == buf.str()); //失败,拾取最后一个std :: setw
GameSalutes

9

我会做

std::wstringstream temp;
ss.swap(temp);

编辑:修复了由christianparpart和Nemo报告的错误。谢谢。

PS:上面的代码在堆栈上创建一个新的stringstream对象,并将所有内容ss与新对象中的内容交换。

好处:

  1. 它保证ss现在将处于全新状态。
  2. 新对象是内联并在堆栈上创建的,因此编译器可以轻松地优化代码。最后,就像将所有ss内部数据重置为初始状态一样。

更多:

  1. 与赋值运算符相比:如果新对象在堆中有分配的缓冲区,则STL交换方法比赋值运算符更快。在这种情况下,赋值运算符必须为新对象分配缓冲区,然后它可能需要为旧对象分配另一个缓冲区,然后将数据从新对象的缓冲区复制到旧对象的新缓冲区。实现快速交换非常容易,例如,它仅交换缓冲区的指针。

  2. C ++ 11。我已经看到了一些移动赋值运算符的实现,它比swap慢一些,尽管可以解决,但是STL开发人员可能不想给移动的对象留下很多数据

  3. std::move()不保证移动的对象为空。return std::move(m_container);不会清除m_container。所以你必须要做

    自动to_return(std :: move(m_container)); m_container.clear(); 返回to_return;

哪个比这更好

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

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

因此swap(),只要适合,我总是喜欢。


2
您应该解释为什么要这样做。这段代码本身并不是非常有用。
Machavity

1
虽然此答案可能是正确的,但请添加一些说明。赋予底层逻辑比提供代码更重要,因为它可以帮助OP和其他读者自己解决此问题和类似问题。
CodeMouse92

我喜欢解决方案。它非常短,并且几乎所有std数据类型都可以使用相同的模板。
martinus

1
这个答案不太正确,因为您可能没有绑定到临时文件,也就是说,您创建了一个临时变量,以将新(临时)创建的空字符串流与现有的“ ss”交换。不允许。
christianparpart

这不是招致构造语言环境的所有开销吗?应该避免重置字符串流吗?
封顶

2

基于上述答案,我们还需要重置所有格式。总之,在构造新的std :: stringstream实例时,我们将重置缓冲区内容,流状态标志以及所有格式为其默认值。

void reset(std::strinstream& stream)
{
    const static std::stringstream initial;

    stream.str(std::string());
    stream.clear();
    stream.copyfmt(initial);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.