seekg()读取文本文件时奇怪的偏移量

我试图得到文件的最后一行,使用这里描述的逻辑最快的方式来只读取文本文件的最后一行? ,但我得到一些奇怪的exception:

score.seekg(-2, ios::cur); 

重置我的stream到相同的字符,所以我得到无限循环。 但是,将其设置为-3完美:

 fstream score("high_scores.txt"); //open file if(score.is_open()) //file exist { score.seekg(0, ios::end); char tmp = '~'; while(tmp != '\n') { score.seekg(-3, ios::cur); if((int)score.tellg() <= 0) //start of file is start of line { score.seekg(0); break; } tmp = score.get(); cout << tmp << "-"; } } 

再次,问题是 – 这个代码只适用于seekg()偏移-3 ,理论上,它应该与-2 。 这能解释一下吗? 文件内容是这样的(文件结尾的换行符):

 28 Mon Jul 10 16:11:24 2017 69 Mon Jul 10 16:11:47 2017 145 Mon Jul 10 16:53:09 2017 

我正在使用Windows,所以现在我明白为什么我需要从文件的末尾-3偏移(传递CRLF字节)。 但是让我们考虑第一个字符(从最后)。

 28 Mon Jul 10 16:11:24 2017 

所以,stream到7 。 它提取它,并移动到CR字节。 那么,如果在下一次循环迭代中我们抵消了-3 ,我们将得到0 ,但不是1 ! 但事实上,我得到1 ! 而所有的工作正常-3偏移量。 这对我来说是个谜。 无法摆脱我的头脑。

我希望这说明了正在发生的事情:

 28 Mon Jul 10 16:11:24 2017CL <- C = CR, L = LF 6543210 <- position relative to ios::end | || | | || * Start after seekg(0, ios::end) | *| After first seekg(-3, ios::cur) | * After first get() * After second seekg(-3, ios::cur) 

当您寻求SEEK_END ,将流位置指针移至文件末尾的字节。 如果你寻求-3,你跳过CR,LF,最后在'7' 。 你读这个字节,但是这将指针移动一个字节。 然后你又回到三点,最后到达'0'

请注意,文件中的行尾实际上是两个字节(CR和LF)。 只是当你阅读他们时,他们被转换成一个'\n' 。 然而,当你寻求它只是使用字节偏移到实际的文件。 这就是为什么人们要么推荐你只是从头到尾阅读文件,或者你以二进制模式打开文件,以消除这种二分法。