I'm looking for a way to set my get pointer at position x from the end of an fstream.
I tried
file.seekg(-x, ios_base::end);
But according to this question, this line is undefined behavior.
If you want to set your pointer at position x from the end, you need to know where the end is, so you need to begin with:
file.seekg(0, ios_base::end);
int length = file.tellg();
When you will know the file length, you can set your pointer:
file.seekg(length - x, ios_base::beg);
THe problem is related to the text mode, which may convert certain sequences of bytes in the file into a sequence of different size.
Take for example text mode under windows. Here the byte sequence '\r' '\n'
in a file on the disk is converted at reading time into '\n'
. Now imagine that you have a file:
Hello\r\n
World\r\n
If you position yourself at file.seekg(-1, ios_base::end);
the result is undefined, because it's not clear what the result should be:
'\n'
? But in this case, reading the file in the reverse order would be inconsistend with reading the file in the correct order. '\r'
, as '\r' '\n'
should be understood as a single byte ? But in this case the positionning would have to be done byte by byte, and for every byte the library would have to check the previous one, just in case of. This is by the way also the reason why you should only directly seekg()
to postions previously aquired by tellg()
.
If you really have to do this kind of positionning from the end, if you open the file as ios::binary
because then you're assured that a byte is always a byte whether counting from the end or counting from the beginning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With