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 では改行記号の長さが 2 バイトであることです。テキスト ストリームはそれを 1 バイト シンボルに変換する'\n'ので、プラットフォームと実際に使用されるバイト シーケンスの違いを気にする必要はありません。

したがって、最初の読み取りでは、たまたま ASCII と同じ値を持つ 2 バイトの endline シンボルの最後のバイトが読み取られます'\n'。次の読み込みは 2 バイトの endline シンボルの先頭にあり、ストリームはそれを正しく に変換し'\n'ます。

于 2016-08-04T10:05:51.297 に答える