2009-07-24 1 views
0

ファイルをサイズがBLOCK_SIZE(現在は1000 unsigned chars)のブロックに読み込もうとしています。私のコードは、ファイル全体(通常は2〜4)を読み込むために読み込まなければならないブロックの数を最初に見つけ、その後ファイルを読むforループを繰り返します(後で "+17+filenamesize"のものを無視しますプログラムで。fread()とfseek()を使用しているCのファイルの一部を読み取る

はしかし、初回のみ、j=1に、それは実際にbuf配列にデータを入れるん。他のケースでは、ときj != 1strlen(buf)戻り。

私はこの問題を考えますファイルを読み取る前にファイルの2番目の部分を探すためにfseek()を使用するか、またはメモリ割り当ての問題です。

1000-1999thの文字をbufアレイに読み込むことについて助けがあれば、どんな助力もあります。

unsigned char *buf; 
source = fopen(localpath,"r"); 
temp = filesize/BLOCK_SIZE + 1; 

for (j=1; j <= temp; j++) { 
    if (j == 1) { 
    buf = (unsigned char *) malloc((sizeof(unsigned char)) * (BLOCK_SIZE + 17 + filenamesize)); 
    fread(buf+17+filenamesize, sizeof(unsigned char), BLOCK_SIZE, source); 
    } else if (j == temp) { 
    buf = (unsigned char *) malloc((sizeof(unsigned char)) * (filesize + 5 - BLOCK_SIZE*(j-1))); 
    fseek(source, BLOCK_SIZE*(j-1), SEEK_SET); // off by one warning 
    fread(buf+5, sizeof(unsigned char), filesize - BLOCK_SIZE*(j-1), source); 
    } else { 
    buf = (unsigned char *) malloc((sizeof(unsigned char)) * (5+BLOCK_SIZE*(j-1))); 
    fseek(source, BLOCK_SIZE*(j-1), SEEK_SET); // off by one warning 
    fread(buf+5, sizeof(unsigned char), BLOCK_SIZE, source); 
    } 
    // do stuff with buf here 

    buf = ""; 
    free(buf); 
} 
+0

ファイルはバイナリかASCIIか。 – EFraim

+0

ところで、実際にはfseekを使う理由は何ですか?あなたの現在のコードは、すべてのfseekを完全に熟練し、より幸せに生きることができます。 – EFraim

+0

ファイルはASCIIです。あなたは正しい、私はおそらくfseekを使用する必要はありません。 freadは読み込みを中断した場所のファイルポインタをそのまま残します。 –

答えて

3

fseekfreadの結果を確認することをお勧めします。特に、fseekが0を返していることを確認します。そうでない場合、これは問題全体である可能性があります。

fseekが成功した場合、freadは読み込まれた合計バイト数を教えてください。

また、strlenは必ずしも有効なものではありません。これは、これがヌル終了文字列であると想定されるためです。読み込んだ最初の文字が0バイトの場合、strlenは0を返します。これはヌル終了文字列として扱われません(ヌルターミネータに十分なスペースを割り当てていません - バイナリデータに合わせるために必要なもの) strlenはおそらく不適切です。

+0

ありがとう、実際には文字列がヌル文字で始まっていたのが問題でした。これは修正されました。また、nullで終了するようにしました。今は正常に動作しています。 –

0

列(第0バイトの前にバイトの数)の長さを返しsrtlen:添付

コードの関連部分です。 buf [0]が0の場合、0を返します。freadの戻り値を使用して、実際に読み取られるバイト数を決定します。

また、メモリリークがあります。すべてのループ反復でmallocを使用できますが、最後には1回だけ解放してください。

+0

彼はループの中で無料で電話する - それは彼の問題ではない.... –

+0

あなたは正しい。漏れはありません。 – stribika

+0

リークがあります。彼は静的ポインタ( "")にbufを割り当ててからfree()しようとします。それは最初に働いてはいけません。 –

2

buf = "";は私のバグのようです。これはポインタbufを定数文字列に設定し、次の行でfree()も試します。私はこの行をスキップします。

また、バッファにいくつかのオフセットを読み込んでいるようです。 2つの後のケースでは+5になります。バッファの最初の部分は未定義です。マニュアルページを参照してください。だからstrlen(buf)私のために未定義と感じる。

+0

結局、リークがあります。文字列だけが解放されます。 "私はそれがクラッシュする可能性があると思う。 – stribika

+0

そのリークを指摘してくれてありがとう - 私は今それを修正しました。 –

0

なぜfseekを使用しているのですか? 「ブロックを何回読み取るかをファイルがどのくらい大きく取っているかを最初に確認する」という概念は根本的に欠陥があります。左のデータがなくなるまで、あなたは、単にたとえば、データを読み込む必要があります。

 
while(BLOCK_SIZE == (read_count = fread(buf, sizeof *buf, count, source)) 
    do_stuff_with_buf(buf, read_count); 

if(ferror(source)) 
    /* Handle error */; 

を(この例では、短い読み取りに_ BUF()で_もの_を行う呼び出すことはありませんが、それは些細な変更です。 )

関連する問題