Erasing from an ostream?

Started by
4 comments, last by Stevieboy 17 years, 10 months ago
Hi! I'm writing a little console with SDL and so far so good. You can now register input/output streams (I just re-use cout and cin) and they go to the screen (which is drawn with bitmap-fonts). The console internally stores a std::stringstream which gives it's streambuf to other input/output streams so that they write to it. Now, since I register std::cout with it, I can output freely. But when I type, I want to use back-space. Now, I know that backspace is '\b', but when I add that [cout << '\b';] I get a white square with a circle in it... Any ideas of how to do this? Or would I be better off not registering cout and simply registering a fresh new stringstream and then manipulating it's str() member? Thanks! Here is the square-circle thingy! Image Hosted by ImageShack.us
Advertisement
You can't erase out of an output stream because it's an output *stream* - it's not a container of stuff: when you send something to it, it gets output and forgotten. You can't put the toothpaste back in the tube.

However, a std::stringstream isn't simply an output stream: it has an underlying buffer. So you can implement a function of your console object which grabs and manipulates the stringstream buffer, like so:

void console::backspace() {  std::string buffer = my_stream.str();  buffer.resize(buffer.size() - 1);  my_stream.str(buffer);}


But this is kind of inefficient :\ What you really want to do is manipulate the streambuf itself, and I'm afraid I don't know enough to help you with that.

You could also maybe try using a *string* buffer, and just wrapping it with a temporary stringstream when adding non-textual stuff? (Or just use boost::lexical_cast with the string operator+?)
Quote:Original post by Zahlman
You can't erase out of an output stream because it's an output *stream* - it's not a container of stuff: when you send something to it, it gets output and forgotten. You can't put the toothpaste back in the tube.

However, a std::stringstream isn't simply an output stream: it has an underlying buffer. So you can implement a function of your console object which grabs and manipulates the stringstream buffer, like so:

void console::backspace() {  std::string buffer = my_stream.str();  buffer.resize(buffer.size() - 1);  my_stream.str(buffer);}


But this is kind of inefficient :\ What you really want to do is manipulate the streambuf itself, and I'm afraid I don't know enough to help you with that.

You could also maybe try using a *string* buffer, and just wrapping it with a temporary stringstream when adding non-textual stuff? (Or just use boost::lexical_cast with the string operator+?)


Hmm... First of all, I would like to thank you for trying to help me...

Second, let's analyze. I looked at a reference for std::streambuf, but at a quick (well, not exactly "quick") glance there only seem to be routines for writing characters directly and reading characters directly. If some guru that goes really low-level with stuff is able to help I'd be really glad ;).

I'll try the other approaches. I'll be creating extra strings either way, so I guess it won't really matter. I bet the over-head won't be THAT big, but oh-well.

Anyways, if someone knows about streambufs please talk [lol].

Thanks right now and in advance.

I believe the "underlying" thing is stringbuf, anyway, this works:

stringbuf sbuff;

sbuff.sputc('a');
sbuff.sputc('b');
sbuff.sputc('c');

char buff[100];
memset(&buff, 'a', 100);

sbuff.sputn(buff, 100);

Not sure how you would get it out of the stringstream though. There are a bunch of other methods as well.

Don't use memset() in C++; use std::fill :)

Anyway, I still don't see a way to *remove* stuff from a stringbuf() - at least, not at the writing end :\
Yeah I was going to say, it doesn't really do much more (or different) than he's got already.

This topic is closed to new replies.

Advertisement