6

I have a string whose last part(suffix) needs to be changed several times and I need to generate new strings. I am trying to use ostringstream to do this as I think, using streams will be faster than string concatenations. But when the previous suffix is greater than the later one, it gets messed up. The stream strips off null characters too.

#include<iostream>
#include<sstream>

using namespace std;

int main()
{
  ostringstream os;
  streampos pos;
  os << "Hello ";
  pos = os.tellp();
  os << "Universe";
  os.seekp(pos);
  cout<<  os.str() << endl;
  os << "World\0";
  cout<<  os.str().c_str() << endl;
  return 0;
}

Output

Hello Universe
Hello Worldrse

But I want Hello World. How do I do this? Is there anyother way to do this in a faster manner?

Edit: Appending std::ends works. But wondering how it works internally. Also like to know if there are faster ways to do the same.

balki
  • 26,394
  • 30
  • 105
  • 151
  • 1
    No so sure that stringstream will be the most efficient - you should consider one of the variants of `std::string::replace()` – Nim Jul 14 '11 at 08:14

3 Answers3

10

The string "World" is already null-terminated. That's how C strings work. "World\0" has two \0 characters. Therefore, operator<<(ostream&, const char*) will treat them the same, and copy all characters up to \0. You can see this even more clearly, if you try os << "World\0!". The ! will not be copied at all, since operator<< stopped at the first \0.

So, it's not ostringstream. It's how C strings aka const char* work.

MSalters
  • 173,980
  • 10
  • 155
  • 350
3

It doesn't strip anything. All string literals in C++ are terminated by NUL, so by inserting one manually you just finish the string, as far as anyone processing it is concerned. Use ostream::write or ostream::put, if you need to do that — anything that expects char* (with no additional argument for size) will most likely treat it specially.

os.write("World\0", 6);
Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
0

Why do you think a stream operation is faster than a string? And why build the string before outputting to cout?

If you want a prefix to your output you could just do it like this

const std::string prefix = "Hello ";

std::cout << prefix << "Universe" << std::endl;
std::cout << prefix << "World" << std::endl;
Bo Persson
  • 90,663
  • 31
  • 146
  • 203