我正在尝试使用此处描述的逻辑Fastest way to read only last line of text file?获取最后一行文件,但我得到了一些奇怪的异常:
score.seekg(-2, ios::cur);
将我的流重置为相同的字符,因此我得到无限循环。但是,将其设置为-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 字节)。但是让我们考虑第一个char(从结尾)。
28 Mon Jul 10 16:11:24 2017
因此,流转到7
。它将其提取出来,并移至 CR 字节。然后,如果在下一个循环迭代中我们将其-3
偏移,我们将获得0
,但不会1
!但实际上,我得到了1
!并且所有工作正常-3
偏移。这对我来说是个谜。无法理解我的想法。
答案 0 :(得分:2)
我希望这能说明发生了什么:
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'
。但是,当您搜索时,它只是将字节偏移量用于实际文件中。这就是为什么人们建议您从头到尾阅读文件,或者以二进制模式打开文件以删除这种二分法。