【发布时间】:2017-07-10 14:41:22
【问题描述】:
我正在尝试使用此处描述的逻辑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 字节)。但是让我们考虑第一个字符(从结尾)。
28 Mon Jul 10 16:11:24 2017
所以,流到达7。它提取它,并移动到 CR 字节。那么,如果在下一次循环迭代中我们将其偏移-3,我们将得到0,但不是1!但实际上,我得到了1!并且在-3 偏移量下一切正常。这对我来说是个谜。我无法摆脱它。
【问题讨论】:
-
请提供minimal reproducible example。很难看出问题在您的问题中的哪个位置。
-
这很可能是由行结束样式引起的问题 - DOS vs Unix。
-
在十六进制编辑器或编辑器中查看您的文件,而不是显示文件中每个字符的十进制或十六进制值。另一种方法是以二进制打开文件并以十六进制或十进制显示每个字符。这将显示行尾是 CR、LF (0x0d, 0x0a) 还是仅 LF (0x0a)。
-
@ThomasMatthews 确实,它有 0d 0a 行结尾。 Windows 特定的东西?好的,但这如何影响非结束字符?就像流过去了 0a 和 0d,得到了最后一个字符,移动了 +1 位置。如果现在,我们对当前位置进行 -3 偏移,理论上,我们得到的不是第 2 个而是第 3 个字符(从末尾开始)!但我们获得了第二名……
-
每一行结束字符都计入定位。 -2 应该定位到最后一个字母“7”。 A -3 应该定位到“1”。至少,这是我的理解。
标签: c++ windows file fstream seekg