2012-04-10 8 views
2

私は2つの異なるもののチェックサムを取る関数を書いています。 2つはアーカイブエントリla BSD libarchiveライブラリです。私はGNUのcoreutilsからチェックサムコードを借りました。ファイルのチェックサムを行うためC:コードの重複の例

私のコードは次のようにそのソースからの読み込み:アーカイブエントリから読み込むための私のコードで

unsigned char buf[BUFLEN]; 
size_t bytes_read; 
FILE *fp; 
... 
while ((bytes_read = fread (buf, 1, BUFLEN, fp)) > 0) { ... } 

、対応するコードは

struct archive *ar; 
unsigned char buf[BUFLEN]; 
ssize_t bytes_read; 
... 
while ((bytes_read = archive_read_data(ar, buf, sizeof(buf))) > 0) { ... } 

としてのように見えますそれは、コードの大部分が同じであっても、私はここで2つの異なる機能を持たなければなりません。 freadとarchive_read_dataは同じ数の引数を持っていないので、私は関数ポインタを渡すことによってそれをどうやって行うのかはよく分かりません。 (私はfread(3)の代わりにread(2)を使うことから始めることができると思いますが、それは進歩的な生産方法であるとは思えません。)ここでコードの重複を避ける良い方法はありますか?関数ポインタを使ってそれをしようとするのとは別に、同じコード部分を別々のファイルに入れて、次に #includingを入力することでそれを実行できますが、それは醜いようです。

この特定の例では、関数のコードはあまり長くないので、コードを複製するだけではあまり問題はありません。私はちょうど洗練されたソリューションが存在するかどうか疑問に思います。

答えて

2

プロトタイプが同じfread()archive_read_data()の独自のラッパー関数を作成できます。これらのラッパーのそれ​​ぞれには、基になるread()関数を呼び出し、必要に応じてパラメータを並べ替えるための単一行のコードが含まれています。

次に、コンテキストに応じて2つのラッパーを区別するために関数ポインタを使用します。

  • は、データ・バッファへのポインタ
  • バイトの数はあなたがラッパーを書くことができ
  • を読み取るために、データ・ソースへ

    • ポインタ:

    0

    両方の関数は実際には3つの引数を必要としますfreadの機能にarchive_read_dataと同じ署名を付けます(またはその逆):

    ssize_t my_fread(FILE *fp, char *buf, int len) { 
        return fread(buf, 1, len, fp); 
    } 
    
    1

    チェックサムを解析するコードが同じ場合、それを関数にすることができます。これは中括弧の中の部分です。私の意見では、同じ機能を呼び出す場合、2つの別々のループを持つことはそれほど悪くありません。薄いラッパーと考えることができます。