2017-03-01 3 views
0

fseek()getlineの組み合わせを使用して、linux tailコマンドをcで実装する方法を理解する助けが必要です。fessek()とgetline()を使用してテールコマンドを使用する - アウトオブオーダー

私はfseek()を使用してファイルの最後に到達し、whileループを使用して後方に反復します。

改行文字( '\ n')が検出された場合。私はラインをプリントアウトし、getlineから '\ n'が検出された位置を引く前に、私が到達した位置に戻ります。

「\ n」が検出されない場合、現在の位置iから-2のオフセットを使用すると、後方に反復されます。

私はバッファを含むtailコマンドを実行する方が簡単だが、アルゴリズムは正しいと思いますか?もしそうなら、それを実装する最良の方法は何か。

ありがとうございます。

void tail(FILE *ifp, int k) { 
    int line_count=0; 
    char *line=NULL; 
    size_t len=0; 

    //go to end of file 
    if(fseek(ifp,-1,SEEK_END)) { 
     fprintf(stderr,"Failure in reaching end of file\n"); 
    } 

    //while loop which will iterate backward starting at the end of file until line_count = k. 
    while(line_count != k) { 
     //if detected a newline character, increment line_count, print out line then return back to previous position.   
     if(fgetc(ifp)=='\n') { 
      getline(&line, &len, ifp); 
      printf("%s", line); 
      fseek(ifp,-strlen(line), SEEK_CUR); 
      line_count++; 
      //free(line); 
     } else { 
      //move back a single positon 
      fseek(ifp,-(strlen(line)+2), SEEK_CUR); 
     } 
    } 
    //free(line); 
    fclose(ifp); 
    printf("-----\nfunction exited\n-------\n"); 
} 

答えて

0

次のいずれかを実行できます

  • バッファ内の最後のN行を保ち、前進、OR

  • スタートファイルの末尾から後方Nラインを行きます。

第2のアプローチは、任意のファイルサイズを考慮すると効率的です。だからあなたのアプローチは上質で、効率的なアプローチです。 しかし、あなたのコードは動作する必要があります。

コードでは、k行未満のファイルがあるかどうかを確認したい場合があります。詳細についてはGNU hereのテールの実装を見てください。

1)メモリリーク:最後に解放するgetlineのニーズに割り当てられたメモリ:あなたは'\n'を打つとき

if(line) 
    free(line) 

2)(あなたのiftrueなります)あなたはまだ考えて(最初の後方に行く必要がありますファイル内の最後の'\n'で何が起こるかについて、最初に'\n'となります)。ただし、コードはgetlineを実行します。

3)あなたのelse単一の位置を求めていない、それはstrlen(line)前回はなく、現在の行の値に依存し、あなたは、このことによって、いくつかの'\n'が求める欠場したり、違法である場合があります求めるかもしれない - >それを確認してくださいあなたは後方に行く間にファイルの最初のパスを打つことはありません。

+0

ありがとう、私は '\ n'に問題があり、それを実現した直後です。私は間違いなくあなたの答えを逆のファイルを読むときの将来の参照として使用しています、もう一度ありがとうございます。 – Omar

関連する問題