0
gcc (GCC) 4.7.0
c89

こんにちは、

私は、fwrite と fread しようとしている次の構造を持っています。

ただし、私のデバイスとリソースはポインターであるためです。fwrite は、データではなくポインター値を読み取ります。デバイスまたはリソースに配列を使用できません。動的に割り当てる必要があるため、ポインターのみ。

書き込む前に、すべてのメモリを構造要素に割り当てます。スニペットを短くしたいので、ここには表示されません。自由にすることもありません。

私の fread 関数では、fread がこれらのメモリ位置に読み込まれるように、デバイスとリソースにメモリを割り当てます。ただし、これは機能しません。

これを行う最善の方法は何ですか?

アドバイスありがとうございました。

struct data {
    int id;
    int set;
    char *device;
    char *resource;
};

struct database {
    struct data **db_data;
    size_t database_rows;
    size_t database_data_size;
};

int database_write(FILE *fp, const struct database *db)
{
    rewind(fp);

    if(fwrite(*db->db_data, sizeof(struct data), 1, fp) == -1) {
        return DATABASE_ERROR;
    }

    return 0;
}

struct database* database_read(FILE *fp, size_t db_rows, size_t db_data_size)
{
    struct database *db = NULL;
    size_t i = 0;

    db = malloc(sizeof(struct database));

    db->database_rows = db_rows;
    db->database_data_size = db_data_size;
    db->db_data = malloc(sizeof(struct data) * db_rows);

    for(i = 0; i < db_rows; i++) {
        db->db_data[i] = malloc(sizeof(struct data));
        db->db_data[i]->device = malloc(db_data_size);
        db->db_data[i]->resource = malloc(db_data_size);
    }

    rewind(fp);

    if(fread(*db->db_data, sizeof(struct data), 1, fp) == -1) {
        return NULL;
    }

    return db;
}
4

3 に答える 3

1

deviceresourceが可変長の場合は、 のサイズとdeviceデータを書き留める必要があります。についても同じことを行いresourceます。それらを読み返すと、サイズを読み取ってからメモリを割り当て、最後に値を読み取ることができます。

于 2012-09-25T10:47:41.533 に答える
1

あなたは自分の質問に答えたようです.freadとfwriteは、メモリにあるものを見て、それをファイルに入れます. これは、ポインターを持たないもの (例えば、数値の大きな配列) を書いている場合にうまく機能します。ポインターを使用して構造体を記述するようには設計されていません。

このファイルにフォーマットがある場合は、フォーマットが示すとおりにする必要があります。途中でフォーマットを作成している場合は、各メンバーを 1 つずつファイルに書き込む必要があります。読み込むにはある種のバッファが必要です (最大長の指定がない場合は、これのサイズを変更する必要があるかもしれません)。また、database_write 関数もかなり変更する必要があります。

于 2012-09-25T10:45:01.917 に答える
1

あなたは自分の問題を説明しました。fwrite は、値ではなくアドレスを書き込みます。

構造体「構造体データ」でデバイスとリソースの長さのフィールドを使用できる場合があります。この長さを読み書きする fread() と fwrite() のラッパーを作成します。このラッパーでは、一時バッファー内のデバイス、リソースを memcpy し、その上で fwrite() を使用できます。

これはシンプルで非常に基本的なソリューションです。

ネットワークでパケットを送信している間、通常、char ポインターを含む構造体が表示されます。最初の 4/8 バイトにはデータの長さが格納され、残りのバイトには実際のデータが含まれます。ユーザーはパケットを読み取り、最初に最初の 4/8 バイトを読み取ります。これに応じて、残りのデータを読み取るために read() 呼び出しが発行されます。

「構造ハック」は技術的に未定義の動作ですか?

于 2012-09-25T10:52:01.537 に答える