tags:

views:

205

answers:

4

I know all kinds of ostreams holds their own internal buffers. I have to know whether there is some kind of ostream which accept an instance std::string and write on that instance.

(I want to avoid redundant copies)

Note: My question is about the standard library, don't offer me other libraries that can do that, I know they exist. :)

Edit: After a request to be more specific ... Here is what I want, consider the following code:

std::string str = "bla bla bla ";
std::ospecialstream o(str);
o << 34 << " bla bla";
std::cout << str; //console output : "bla bla bla 34 bla bla"

I want ospecialstream such that it won't copy str contents into some internal buffer but rather write to the same instance of str.

Edit #2 I need it for performece reasons , ostringstream will make a memcopy when created with a string and will also make a memcpy when the contents are retrieved.

+3  A: 

std::ostringstream part of sstream header.

How about this:

void appendStuff(string& in) {
   ostringstream os;
   os << 34 << " bla bla";
   in += os.str();
}
dirkgently
ostringstream holds its own stringbuf.
Pontus Gagge
@Pontus Gagge: Yes, of course it does. IMO this is what the OP wants.
dirkgently
That doesn't help for two reason . I want an ostream that will be built upon a predefined string.Another problem is that when I want to retrieve the string from ostringstream , it will give me another copy.
@dirkgently: well, not what the OP asked for, but I agree that it's what's needed (rather than hacking around inside an exsting std::string).
Pontus Gagge
Edited the question, please havea look , thanks
@yossi1981: Since this is a very specific requirement (no copies), you will probably have to roll your own. I'd still go with ostringstream (is the copy the only binding factor?)
dirkgently
copy is the only thing that disturb me , my profiler shows me that ostringstream is a bad boy , I assume that this is because it holds its internal data , I can improve the performence simply if i had that special ostream.
I'm referening to your edited post: that resolve one copy but I Have to problems with it, one is that when the str is retrieved from the os there is a copy and the second one is that will require me to change many places in the code , I still may consider your solution though, +1 for your efforts :)
+2  A: 

If you are asking can you alter the buffering of ostreams, then the answer is yes. However, depending on what you actually want the buffer to do, this is not a particularly simple task. You will want to consult a book like Langer & Kreft for more info.

L&K have an example of how to implement an unbuffered output stream - it begins on page 229 of the book. It's too long to reproduce here, but basically you need to redefine the overflow() method of a derived streambuf class.

Note the book is not available on-line but the source code apparently is - see this page for details.

anon
I'll refer to that book , I guess I can consider your post a good answer , +1 , thanks
+1  A: 

Short answer: no

Long answer: Yes, but this requires writing your own streambuf class, which you then set with rdbuf. Also, now deprecated strstream does almost what you want and may still be in your compiler libraries.

eidolon
+1  A: 
#include <iostream>
#include <string>

class intostring : public std::basic_streambuf<char> {
  std::string &str;
public:
  intostring(std::string &pstr):str(pstr) {}
  virtual std::streamsize xsputn(const char *const p, const std::streamsize n) {
    str.append(p, n);  
  }
};

int main() {
  std::string s("Original string: ");

  intostring newbuf(s);

  std::streambuf *oldbuf = std::cout.rdbuf(&newbuf);
  std::cout << "Should go to string" << std::endl;
  std::cout.rdbuf(oldbuf);  

  std::cout << "Should go to console again ... and here's the string: '" 
            << s << "'" << std::endl;
}

Outputs:

Should go to console again ... and here's the string: 'Original string: Should go to string'