0

fread と fwrite を使用して構造体をファイルに読み書きする必要がある本のプログラムを読みました。

struct Address {
    int id;
    int set;
    char *name;
    char *email;
}

struct Database {
    int rows;             //number of rows
    struct Address *row;  //pointer to a row in the database
}

struct Connection {
    FILE *fp;
    struct Database *db
}

すべての構造体にメモリを割り当て、id の値を初期化し、アドレス構造体とデータベース構造体の行に設定します。

次に、構造をファイルに書き込みます。

int fc = fwrite(conn->db, sizeof(*conn->db->row) * number + sizeof(int), 1, conn->fp);
if(fc != 1) printf("Error");

今、ファイルから conn->db->rows の値を読み取ろうとしています

int fc = fread(&conn->db->rows, sizeof(int), 1, conn->fp);

セグメンテーション違反が発生します。

今、これはファイルから変数を読み取る正しい方法ではないと推測しています。このコードを機能させるのを手伝ってくれる人はいますか?

4

2 に答える 2

1

どのように書いたり読んだりするかについての計画が必要ですstruct Address。簡潔にするために、setandemailフィールドは無視します。文字列の境界を設定する場合は、その方法を決定する必要があります。\n使いやすいように末尾を使用しfgets()ました。intがバイト (2、4、8、...) または ASCII 文字として読み書きされるかどうかを判断する必要があります。使用される OP の例fwrite()、fprintf() & "%d" をお勧めします。

もちろん、関数をrows何度も呼び出します。

int WriteAddress(FILE *f, const struct Address *A) {
  size_t L = A->name ? (strlen(A->name) + 1) : 0;
  if ((1 != fwrite(&(A->id), sizeof(A->id), 1, f)) ||
     (L != fwrite(A->name, 1, L, f)) ||
     (1 != fwrite("\n", 1, 1, f))) {
    return  1; // failure
  }
  return 0; // No problem
}

int ReadAddress(FILE *f, struct Address *A) {
  A->id = 0;
  A->name = 0;
  #define MAXNAME (1000)
  char buf[MAXNAME+1];
  if (1 != fread(&(A->id), sizeof(A->id), 1, f)) return 1; // error
  if (fgets(buf, sizeof(buf), f) == NULL) return 1; // error
  A->name = strdup(buf);  // could check for NULL here
  return 0;
}

堅牢なソリューションは自明ではありません-エラーチェックによっては、文字列の最大長、intライターとリーダーの範囲の違い、名前の印刷不可能な文字の処理方法、ファイルエラー、メモリの解放、NULL 名など.

于 2013-07-20T14:34:54.557 に答える
1

あなたは fread に関するドキュメントを読んでいないと思います。man fread
でチェックアウトしてください

このようにファイルをバッファに読み込みます

int fc = fread(ptr, sizeof(int), 1, fp);

ptrは、ファイルの内容が読み込まれるメモリへのポインタです。

于 2013-07-20T12:35:06.017 に答える