Reputation: 2311
The following program should output something like:
Begin found
space found
End found
but it doesn't.
#include <sstream>
#include <istream>
#include <string>
#include <cctype>
#include <iostream>
bool Match(std::istream& stream, const std::string& str)
{
std::istream::pos_type cursorPos = stream.tellg();
std::string readStr(str.size(),'\0');
stream.read(&readStr[0],str.size());
stream.seekg(cursorPos);
if(std::size_t(stream.gcount()) < str.size() || readStr != str)
return false;
return true;
}
bool Take(std::istream& stream, const std::string& str)
{
if(!Match(stream,str))
return false;
for(std::string::size_type i = 0; i < str.size(); ++i)
stream.get();
return true;
}
int main()
{
std::string testFile = "BEGIN END";
std::stringstream ss(testFile);
auto c = ss.peek();
while(!ss.eof() && ss.tellg() != -1)
{
if(Take(ss,"BEGIN"))
std::cout << "Begin found" << std::endl;
else if(Take(ss,"END"))
std::cout << "End found" << std::endl;
else if(std::isspace(c))
{
ss.get();
std::cout << "space found" << std::endl;
}
else
std::cout << "Something else found" << std::endl;
}
return 0;
}
What I've noted is that it outputs
Begin found
Something else found
When I step through with the debugger, it appears that when I'm up to the space character it first checks if there's a Match()
to "BEGIN"
, it retrieves the cursor position through tellg()
, which has a value of 5
. But then when it fails expectedly and then checks for a Match()
with "END"
, the cursor is at -1
, i.e. the end.
So it appears that the seekg()
call isn't working, or I'm not using it correctly.
Upvotes: 0
Views: 96
Reputation: 4016
When your program enters the main loop, it first executes take with the input stream and "BEGIN" as arguments. Match returns true, and get is called 5 times as that's the length of BEGIN.
Then it goes through the loop again. It calls match again. At this point pos is at 5, the length of BEGIN. It tries to read len(BEGIN) characters, but your stringstream doesn't have that many characters, so it leaves the loop at position -1, and sets an error flag.
Because the stream is an error state, the following seekg call does not have the intended effect, explaining the behavior of your program.
Upvotes: 1