8

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?
Community
  • 1
  • 1
user2962533
  • 397
  • 1
  • 5
  • 18

2 Answers2

10

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);
Blood
  • 4,126
  • 3
  • 27
  • 37
9

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 positioned at the '\n'? But in this case, reading the file in the reverse order would be inconsistent 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 positioning 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 positions previously acquired by tellg().

If you really have to do this kind of positioning 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.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Christophe
  • 68,716
  • 7
  • 72
  • 138