0
// Print the last n lines of a file i.e implement your own tail command
 #include <iostream>
 #include <fstream>
 #include <string>
 int main()
 {
  std::ifstream rd("D:\\BigFile.txt");
  int cnt = 0;char c;
  std::string data;
  rd.seekg(0,rd.end);
  int pos=rd.tellg();

   while(1)
  {

    rd.seekg(--pos,std::ios_base::beg);

      rd.get(c); 
      if(c=='\n')
      {
          cnt++;
         // std::cout<<pos<<"\t"<<rd.tellg()<<"\n";

      }

      if(cnt==10)
        break;

 }
       rd.seekg(pos+1);
       while(std::getline(rd,data))
     {
        std::cout<<data<<"\n";
     }



    }

因此,我编写了这个程序来打印文本文件的最后 10 行。但是它只打印最后 5 ,由于某种原因,每次遇到实际的 '\n' 时,下一个 get() 也会给出一个 \n 导致不正确的输出。这是我的输入文件:

Hello
Trello
Capello
Morsello
Odello
Othello
HelloTrello
sdasd
qerrttt
mkoilll
qwertyfe 

我在 Windows 上使用记事本,这是我的输出:

HelloTrello
sdasd
qerrttt
mkoilll
qwertyfe

我无法弄清楚为什么会这样,请帮忙。

4

1 回答 1

3

如果文件以文本模式打开,请勿对文件位置使用算术运算。它不会给你正确的结果。

如果文件以文本模式打开,1 个字符并不总是意味着 1 个字节。文件位置是如何实现的(如果它指向特定的字符或字节)是未指定的。

在您的情况下,问题是在 Windows 上,换行符是两个字节长。文本流将其转换为单字节符号'\n',因此您无需担心平台和实际使用的字节序列之间的差异。

因此,您的第一次读取会读取两字节结束符号的最后一个字节,该符号恰好与'\n'ASCII 中的值相同。下一个读取位于两字节尾行符号的开头,并且流正确地将其转换为'\n'.

于 2016-08-04T10:05:51.297 回答