get()的异常行为(从c++中的文件读取)

Unusual behaviour of get() (reading from a file in c++)

本文关键字:文件 读取 c++ 异常 get      更新时间:2023-10-16
// 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个,由于某种原因,每次遇到实际的"时,下一个get((也会给出一个错误的输出。这是我的输入文件:

Hello
Trello
Capello
Morsello
Odello
Othello
HelloTrello
sdasd
qerrttt
mkoilll
qwertyfe 

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

HelloTrello
sdasd
qerrttt
mkoilll
qwertyfe

我不明白为什么会发生这种事,请帮忙。

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

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

在您的案例中,问题是在Windows上,换行符有两个字节长。文本流将其转换为单字节符号'n',所以您不需要担心平台和实际使用的字节序列之间的差异。

所以,您的第一次读取读取两个字节的结束线符号的最后一个字节,该符号恰好和ASCII中的'n'具有相同的值。下一次读取落在两字节结束线符号的开头,流将其正确转换为'n'