• 12
• 12
• 9
• 10
• 13

# stringstream problems

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

## Recommended Posts

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!
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 on other sites
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 on other sites
Quote:
 Original post by Beer HunterReadBuffer << 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 on other sites
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.