SK said:
I am searching for a string (say "ABC") backwards in a file.
First I seek to the end.
Then I try to make a check like -
do {
file.clear ();
file.get(c);
file.seekg(-2, std::ios::cur);
} while (c != 'A' && c.readback() != 'B' && c.readback != 'C')
// readback, hypotheticl func, problem here)
Is there some function/trick like peek that can instead read backwards
one character at a time?
Or is there a better way to solve this problem.
This approach seems fine to me. Others suggested reading the file into
blocks of strings. But I'm not sure if there's a need to do this as the
default fstreams already read the file into blocks of strings (though the
standard requires them to, but they do for file streams). As for how they
normally handle reading from the end of the file, I don't know for sure, but
I think it's like this: when the user reads the last character, then read
the last N chars into memory where N is the size of a block, position the
streambuf's get pointer to the last character, return the character at the
get pointer.
file.get(c);
file.seekg(-2, std::ios::cur);
The above might be more clearly expressed with
c = file.peek();
file.seekg(-1, std::ios::cur);
Also, since you're looking for a string of length 3, you could save the last
3 chars read into variables like c1, c2, c3. Or even an array, vector, etc.
Then even if you encounter an 'A' you could ignore it if the next characters
are not 'BC'.
Finally, to get improved performance you could work directly with the
underlying streambuf. Call file.rdbuf() to get a pointer to the streambuf.
It will really be a filebuf, but pretend you don't know this. To position
the stream to the beginning or end use pubseekpos. To position the stream
relative to the current position use pubseekoff. To get the current
character as in peek use sgetc.
If this is not fast enough, you could even write your own class derived from
filebuf that implements a sbumpcminus() function that gets the current
character then decrements the get pointer. Use setg to set the get pointers
and range of the get area. But this is getting really advanced.
peek at the current character