fstream - 如何 seekg() 以从末尾定位 x

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

我正在寻找一种方法来将我的 get 指针设置在 fstream 末尾的位置 x。

我试过了

file.seekg(-x, ios_base::end);

但是根据this question,这一行是未定义的行为。

如果你想把你的指针设置在距离末尾x的位置,你需要知道末尾在哪里,所以你需要从:

开始
file.seekg(0, ios_base::end);
int length = file.tellg();

当你知道文件长度时,你可以设置你的指针:

file.seekg(length - x, ios_base::beg);

问题与文本模式有关,它可能会将文件中的某些字节序列转换为不同大小的序列。

以windows下的文本模式为例。这里磁盘上文件中的字节序列 '\r' '\n' 在读取时被转换为 '\n'。现在假设您有一个文件:

Hello\r\n
World\r\n

如果您将自己定位在 file.seekg(-1, ios_base::end);,结果是未定义的,因为不清楚结果应该是什么:

  • 你应该只是定位在 '\n' 吗?但是在这种情况下,以相反的顺序读取文件与以正确的顺序读取文件是不一致的。
  • 是否应该定位在'\r',因为'\r' '\n'应该理解为一个字节?但在这种情况下,定位必须逐字节完成,并且对于每个字节,库都必须检查前一个字节,以防万一。

顺便说一下,这也是为什么您应该只直接 seekg() 到之前由 tellg() 获得的职位的原因。

如果你真的必须从头开始做这种定位,如果你打开文件为 ios::binary 因为这样你就可以确保一个字节总是一个字节,无论是从头开始计数还是从头开始计数从一开始就。