Sign in to follow this  
nullsquared

Erasing from an ostream?

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
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 :\

Share this post


Link to post
Share on other sites

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