Sign in to follow this  

Erasing from an ostream?

This topic is 4202 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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+?)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

This topic is 4202 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this