1

I want to overwrite the string in an std::ostringstream but std::ends isn't working. Is this a problem with VS2012, or am I doing something wrong? Here is example code:

std::ostringstream foo;

foo << "1,2,3,4,5,6";
std::cout << foo.str(); // prints: 1,2,3,4,5,6
foo.clear();
foo.seekp( std::ios_base::beg );
foo << "A,B,C" << std::ends;
std::cout << foo.str(); // prints: A,B,C,4,5,6 NOT just: A,B,C

EDIT:

I'm getting a lot of answers that I can use foo.str( std::string() ) to clear the string... I know that. This question is a spin off from here: How to reuse an ostringstream? I'm trying not to reallocate the buffer.

Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288

4 Answers4

4

actually it prints

enter image description here

note the [NUL] which corresponds to the std::ends and did overwrote the comma after the 3

the ostringstream::str() function returns a container which tracks its length and ignores any possible line ending charakter.

so to get a format which respects the string ending character you can e.g. use the char * (or wchar_t* if compiling with unicode support) representation obtained via std::string::c_str() like this foo.str().c_str();

Valerij
  • 27,090
  • 1
  • 26
  • 42
  • 1
    So maybe the solution would be to dump it to a `const char*`? Like `foo.str().c_str()`? – Jonathan Mee Jul 09 '14 at 11:28
  • 1
    @JonathanMee: That's a solution if you want to make things more complicated. It would be simpler to empty the stream before reusing it, rather than messing around with weird C-style idioms. – Mike Seymour Jul 09 '14 at 11:29
  • 1
    @MikeSeymour I'd rather avoid reallocing the memory if possible, cause I reuse this stream a lot in code. Though going to a `const char*` is also wasteful. My initial thought on this came from this issue: http://stackoverflow.com/questions/624260/how-to-reuse-an-ostringstream – Jonathan Mee Jul 09 '14 at 11:33
  • @JonathanMee: I'd be surprised if it needed to reallocate the memory after being cleared. It should just reset its internal pointer to the start of its buffer. (But you should check, in the unlikely event that this might be a performance bottleneck). – Mike Seymour Jul 09 '14 at 11:38
  • @MikeSeymour Because the `std::ostringstream` is in a big loop, yes, the memory is being reallocated with `foo.str( std::string() );`. I just wish that there was a way not to stoop to `foo.str().c_str();`. – Jonathan Mee Jul 10 '14 at 11:08
  • @Valerij If you could update your post to recommend that I use `foo.str().c_str();` I will accept it as that is the best solution that has been presented. – Jonathan Mee Jul 10 '14 at 11:09
  • @JonathanMee you can suggest edits to my answer too. thats how this site works - collaboration and peer reviewing – Valerij Jul 10 '14 at 22:21
2

Why are you using std::ends? It is something left over from the days of std::ostrstream, where it ensured that the generated char[] was null terminated. You would not normally want to use it on an std::ostringstream.

In the code you present, it looks to me like what you really want is two separate std::ostringstream (although it is possible to clear the data, by calling foo.str( "" );).

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

If you just want to overwrite the string content, simply use the str(new_string) method like so:

std::ostringstream foo;

foo << "1,2,3,4,5,6";
std::cout << foo.str(); // prints: 1,2,3,4,5,6
// clear just reset error state flags
foo.clear();
// Replace the content of the stream
foo.str("A,B,C");
std::cout << foo.str(); // Should print: A,B,C

or:

// clear just reset error state flags
foo.clear();
// Clear content of the stream
foo.str("");
foo << "A,B,C";
Gall
  • 1,595
  • 1
  • 14
  • 22
0

In 3rd statement foo.clear() does not delete the data in foo. In 4th statement you used the file position to point begining . so next statement takes values from begining so the values 1,2,3 are overwritten by A,B,C

instead of foo.clear() use foo.str("");