2011-06-30 22 views
3

私は、他のファイルへの書き込みが発生するオフセットとそのオフセットで書き込まれるデータをログに記録するバイナリファイルを持っています。私は、ファイルにレコードを書き込むときに今は文字列を含む構造体をバイナリファイルに書き込む

struct log_record{ 
        int offset; 
        char *data; 
       } 
struct log_record t; 

として各ログレコードの構造を定義し、私は、ファイルに書き込み、したがって割り当てる前に、私は

t.data = (char*)malloc(sizeof(char)*strlen(buff));/*buf holds the data to be written*/ 
ように領域を割り当てるデータの長さを有します

今私はファイルに書き込んでいるレコードの長さを持っています...しかし、問題は読んでいる間です。どのようにしてレコードを読み込んだ構造体に対してスペースを割り振り、レコードのサイズになるべきかをfreadに割り振ります。いくつか混乱しています。 助けに感謝します

答えて

3

文字列の長さを可変にする必要があります。

strlen()は、NULLを含むサイズを返さないことに注意してください。

EDIT + EDIT 2(ムーのおかげが短すぎる)+ EDIT 3(MUへの感謝が短すぎる)

これは、私はそれを行うだろうかです:

t.data = (char*) malloc(sizeof(char) * strlen(buff) + 1); 
strcpy(t.data, buff); 

// ... 
int data_size = strlen(t.data) + 1; 
fwrite(&t.offset, 1, sizeof(t.offset), file); 
fwrite(&data_size, 1, sizeof(data_size), file); 
fwrite(t.data,  1, strlen(t.data) + 1, file); 
+0

が、あなたに –

+0

@Jugglerを取得できませんでした:代わりに、ちょうどこれを言う私の編集を確認してください。 – Donotalo

+0

@muが短すぎます:私が提案したものは編集ではありません!私のミスを指摘してくれてありがとう。私は編集するつもりです。 – Donotalo

0

可変サイズの構造体をバイナリファイルに書き込むことはできません。また、構造体のサイズを記録せずに再度読み込むことはできません。 charポインタの代わりに固定サイズのchar配列を使用するか、可変長である必要がある場合は各要素のサイズを記録するカスタムファイル形式を使用することができます。

私はもっと良いことがなかったので、私はあなたが探していることを望む小さなプログラムを書いた。エラーチェックなし。

#include <stdio.h> 
#include <string.h> 
#include <malloc.h> 

typedef struct { 
    int offset; 
    int length; 
    char *data; 
} log_record; 

void write_to_file(const char *filename) 
{ 
    log_record lr; 
    const int num_records = 10; 
    char buf[100]; 
    int i; 
    FILE *fp; 

    fp = fopen(filename, "wb"); 

    for(i = 0; i < num_records; ++i) 
    { 
     sprintf(buf, "Data entry %d goes here. Beware of size limit!", i); 
     lr.length = strlen(buf) + 1; 
     lr.offset = i; 
     lr.data = malloc(sizeof(char) * lr.length); 
     strncpy(lr.data, buf, lr.length); 
     fwrite(&lr.offset, sizeof(lr.offset), 1, fp); 
     fwrite(&lr.length, sizeof(lr.length), 1, fp); 
     fwrite(lr.data, sizeof(char), lr.length, fp); 
     free(lr.data); 
    } 
    fclose(fp); 
} 

void read_from_file(const char * filename) 
{ 
    log_record lr; 
    int tmp; 
    FILE *fp; 

    fp = fopen(filename, "rb"); 

    while (feof(fp) == 0) 
    { 
     tmp = fgetc(fp); 
     if(tmp != EOF) 
     { 
      ungetc(tmp, fp);    
      fread(&lr.offset, sizeof(int), 1, fp); 
      fread(&lr.length, sizeof(int), 1, fp); 
      lr.data = malloc(sizeof(char) * lr.length); 
      fread(lr.data, sizeof(char), lr.length, fp); 
      free(lr.data);  
     } 
    } 
    fclose(fp); 
} 


int main(int argc, char *argv[]) 
{ 
    write_to_file("temp.bin"); 
    read_from_file("temp.bin"); 
    return 0; 
} 
2

構造体全体をディスクに書き込んだり、再度読み込んだりする必要はありません。さまざまなアーキテクチャーに気づいたように、ポインターと可変長のデータ構造に問題があります。代わりに、出力を手作業でマーシャリングし、読み込んだときにデータをまとめて戻します。あなたの特定のケースで

は、代わりにstruct log_recordを書いて、あなたは3つのことを書きたい:

  • offset(あなたのサイズやバイト順序を選択し、それに固執します)。
  • 長さはdata(上記と同じ形式)です。
  • dataの実際のバイト。

次に、データを読み込むときは、offsetを読み込み、ローカルバイトオーダーと一致するようにそのバイトを並べ替えます。その後、長さを読み取る(offsetと同じ方法で)。今度は、freadを一度呼び出すだけで、メモリを割り当ててディスクから抜き取ることができるので、dataの容量がわかります。

オハイオ州と返す値のmallocをキャストしないで、それの必要はありませんし、問題を隠すことができます。申し訳ありませんDonotalo..Am @

/* See above for how to figure out data_length. */ 
t.data = malloc(sizeof(char) * data_length); 
関連する問題