Erasing from an ostream?
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!
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:
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+?)
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 :\
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
Popular Topics
Advertisement