14

I struggle to understand the different behaviours of stringstream from the following code. Can someone shed a light on how stream internally works?

int main(){
    string str = "123";  
    stringstream ss(str);
    cout << ss.str() <<endl;  
    ss << str;
    cout << ss.str() <<endl;
} 

output:

123

123

int main(){
    string str = "123";  
    stringstream ss;
    ss << str;
    cout << ss.str() <<endl;  
    ss << str;
    cout << ss.str() <<endl;
} 

output:

123

123123

4

3 回答 3

6

It's because the actual write position isn't updated, so when you in the first example do

ss << str;

you overwrite the current string.

Use the flag std::ios_base::ate to the constructor of the string stream

std::stringstream ss(str,
    std::ios_base::in | std::ios_base::out | std::ios_base::ate);

to position the read/write pointers at the end.

See the example in this reference.

And it's like that for all streams, when you open a file stream the positions are also at the start.

于 2013-10-16T11:09:08.543 回答
3

std::stringstream object internally remembers the position, where the writing ended last time. This is updated when you use << operator, but not when you use some string to construct this stream:

stringstream ss(str);
cout << ss.tellp() <<endl;  
ss << str;
cout << ss.tellp() <<endl;

outputs:

0
3

i.e. by the time first ss << str; is executed, it just uses "123" to rewrite "123", which is already there. You could use setp to set the position where the next character is to be inserted:

stringstream ss(str);
cout << ss.str() <<endl;  
ss.seekp(3);                 // <-- sets outPUT position
ss << str;
cout << ss.str() <<endl;

Alternatively you might set the mode, which will make sure that this position will be set to the end before every write operation using std::stringstream::app or you can use std::ios_base::ate, which seeks to the end of stream immediately after open:

stringstream ss(str, std::stringstream::out | std::stringstream::app);
于 2013-10-16T11:07:29.670 回答
1

Constructing an std::stringstream sets the position to the beginning of the stream. The position is updated after writing to the stream or when calling the appropriate seek method.

于 2013-10-16T11:09:53.463 回答