我试图得到文件的最后一行,使用这里描述的逻辑最快的方式来只读取文本文件的最后一行? ,但我得到一些奇怪的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
偏移(传递CR和LF字节)。 但是让我们考虑第一个字符(从最后)。
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'
。 然而,当你寻求它只是使用字节偏移到实际的文件。 这就是为什么人们要么推荐你只是从头到尾阅读文件,或者你以二进制模式打开文件,以消除这种二分法。