2015-02-10 163 views
4

我知道stringstream可以使用stringstream::str()进行更新,但是如果在此之后向stringstream输入了其他内容,则不会按预期工作。下面的代码演示的现象:使用stringstream更新后,C++ stringstream无法正常工作:str()

#include <iostream> 
#include <string> 
#include <sstream> 

using namespace std; 
int main() 
{ 
    stringstream ss; //ostringstream gives the same output 
    ss << "Original string "; 
    ss.str("Updated string "); 
    ss << "sth else"; 
    cout << ss.str() << endl; 
} 

我希望得到的输出

Updated string sth else 

但它实际上输出

sth elsestring 

看来,宁可追加在最近输入的字符串当前字符串的结尾(在我的例子中为Updated string),它试图从头开始覆盖它。我的代码有什么问题?

Here's a live demo

+2

当使用stringstream时,你必须处理输入/输出位置和状态 - 避免它,并使用istingstream或ostingstream。 – 2015-02-10 23:20:54

+0

@DieterLücking感谢您的建议。我试过ostringstream,它给出了相同的输出。 – 2015-02-10 23:26:48

+0

另外,不要重复使用它 - 使用一个新的实例,而不是用str来操作缓冲区(....) – 2015-02-10 23:29:17

回答

6

您需要添加std::ios_base::appopenmode。它确保stringstream对象在每次写入之前查找流的末尾。试试这个:

stringstream ss(std::ios_base::app|std::ios_base::in|std::ios_base::out); 
+0

@ user2079303这些值是未指定的,但行为在'27.5.3.1.4 [ios :: openmode ]'。此外,它适用于[ideone](http://ideone.com/WIVW1k)。我从你的版本中分出来,因为你的版本只是传递了'ate'? – Pradhan 2015-02-10 23:55:01

+0

@Pradhan我从'ios_base :: ate'改变了'ios_base :: app',但是我的错误确实是抛弃了'ios_base :: out'。也就是说,'ios_base :: ate'(带'ios_base :: out')也可以,对吗? (以及它在ideone http://ideone.com/dJxnCk) – user2079303 2015-02-10 23:58:40

+0

@ user2079303这很奇怪。我将其解释为意味着寻求结束只能在公开的和预期的'吃'失败[here](http://ideone.com/Z8zi50)。但事实并非如此。 'app'和'ate'都给出了相同的结果。根据[cppreference](http://en.cppreference.com/w/cpp/io/basic_stringbuf/str)和[cplusplus](http://www.cplusplus.com/reference/sstream/stringstream/str)提供的 – Pradhan 2015-02-11 00:06:55