Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fstream - How to seekg() to position x from end

Tags:

c++

fstream

seekg

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.

  • How can I, in any way, seek to position x from the end of a fstream?
like image 340
user2962533 Avatar asked Jul 21 '15 12:07

user2962533


2 Answers

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);
like image 137
Blood Avatar answered Nov 07 '22 18:11

Blood


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:

  • should you simply be positionned at the '\n' ? But in this case, reading the file in the reverse order would be inconsistend with reading the file in the correct order.
  • should it be positioned at the '\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.

like image 8
Christophe Avatar answered Nov 07 '22 18:11

Christophe