Sign in to follow this  
Auron

stringstream problems

Recommended Posts

Auron    328
OK, I had a lengthy explanation, but it's really not needed. Here's my code and the specific problem immediately follows...
string Tokenizer::ReadTag ()
{
	string buffer;
	char c = 1;

	buffer += GetStream ().get ();

	while (c != '>')
	{		
		c = GetStream ().get ();

		if (GetStream ().eof () || c == '<')
		{
                        // PROBLEM HERE!
			ReadBuffer << buffer;
			cout << "Buffer contains " << ReadBuffer.str () << endl;
			
			buffer = "<";
			return buffer;
		}

		buffer += c;
	}

	return buffer;
}

To explain: GetStream() returns a reference to either an istream or ReadBuffer (to allow transparent stream access). ReadBuffer is a std::stringstream used to buffer input that's already been read from stdin but can't be used yet. In this case, this is when you have a tag that opens (<) but doesn't close (&rt;) before another tag opens. As such, I want to scan out the initial < and store everything else that's been read to buffer into ReadBuffer (because cramming an arbitrary number of characters back into the input stream isn't a great idea). The problem lies in that nothing is getting inserted into ReadBuffer. I've looked at scads of docs and they all just say to use the << operator, but it's just not working for me. Now, am I doing something wrong? Or is this another one of those instances where Visual C++ 6's STL implementation is sub-par? Or is it something else...? Thanks in advance for any replies. -Auron

Share this post


Link to post
Share on other sites
Beer Hunter    712
ReadBuffer << buffer; is indeed the correct way to send a string to a stringstream. Your problem appears to be that the stringstream is in the "failure" state when you try to write to it. I/O operations on such streams will silently do nothing. Make sure you haven't tried to read past the end of ReadBuffer somewhere before.

If you do not intend for ReadBuffer to ever be in the failure state, call ReadBuffer.exceptions(ios::failbit) on it in your constructor. Assuming that MSVC 6.0 implements this, it will throw ios::failure from the offending operation.

Otherwise, you can do checks with calls such as ReadBuffer.fail(), and you can set the stream back to a usable state with ReadBuffer.clear().

Share this post


Link to post
Share on other sites
Auron    328
Quote:
Original post by Beer Hunter
ReadBuffer << buffer; is indeed the correct way to send a string to a stringstream. Your problem appears to be that the stringstream is in the "failure" state when you try to write to it. I/O operations on such streams will silently do nothing. Make sure you haven't tried to read past the end of ReadBuffer somewhere before.


That's the thing. I haven't even used it before that point. I tried checking via ReadBuffer.fail() and apparently it's in a fail state before it ever gets to trying to put a string in there.

Would there be any problems with using stringstream::eof()? Because that's what's being called every time GetStream ().eof () appears in the code.

It works fine if I call the ReadBuffer.clear() method every time I intend to write to it, but something about that doesn't seem right.

-Auron

EDIT: As it turns out, calling eof() on a stringstream isn't very useful anyway... it doesn't seem to notice until one character after I reach the end of the buffer and calls to get() return -1 where it should be EOFing. Any insight on that?

Share this post


Link to post
Share on other sites
Beer Hunter    712
I've never really played with stringstreams and eof(), so I don't know what to make of the behaviour you describe. In any case, I belive the problem is in GetStream(). I assume that it looks like this:
istream& Tokenizer::GetStream()
{
if (!ReadBuffer.eof())
return ReadBuffer;
else
return cin;
}
Try changing the check to if (ReadBuffer.peek() != -1) and see how that goes.

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