1

そのため、何らかの理由で、古いデータの末尾に新しいファイルを追加して、データを格納する外部ファイル (.DAT) を作成する必要があります。

#include <stdio.h>
#include <stdlib.h>

int main () {
    typedef struct {
        char *Name;
        int Index;
    } DataFile;

    static FILE *file;
    size_t result;
    DataFile *DataTable;

    file = fopen("database.DAT","ab");
    DataTable = (DataFile *) malloc (sizeof(DataFile));
    DataTable[0].Name = "somefile.txt";
    DataTable[0].Index = 7;
    printf("%s %d \n",DataTable[0].Name,DataTable[0].Index);
    result = fwrite(DataTable,sizeof(DataFile),1,file);
    fclose(file);
    free(DataTable);
    return 0;
}

上記のコードを実行した後、データが正しく保存されているかどうかを確認します。というわけで、以下のコードを作成します。

#include <stdio.h>
#include <stdlib.h>

int main () {
    typedef struct {
        char *Name;
        int Index;
    } DataFile;

    static FILE *file;
    size_t result;
    long size;
    int i;
    DataFile *DataTable;

    file = fopen("database.DAT","rb");
    if (file == NULL) printf("Error1");

    // Determine the size of file
    fseek(file,0,SEEK_END);
    size = ftell(file);
    rewind(file);

    DataTable = (DataFile *) malloc ((size/sizeof(DataFile)) * sizeof(DataFile));
    if (DataTable == NULL) printf("Error2");

    result = fread(DataTable,sizeof(DataFile),size/sizeof(DataFile),file);
    fclose(file);

    for (i=0; i<result; i++) {
        printf("%s %d \n",DataTable[i].Name,DataTable[i].Index);
    }
    free(DataTable);
    return 0;
}

ただし、出力は得られます

somefile.txt 7

最初のコードブロックから

Error1 7

2 番目のコード ブロックから。問題は、.DAT ファイルを開くとき、または DataTable にメモリを割り当てるときに失敗したためではないことに気付きました。また、.DAT ファイルから読み取る場合、int 型 (Index) では機能しますが、char* 型 (Name) では機能しません。この char* 型の読み取りの問題 (および「error1」の原因) を解決するために何をすべきかわかりません。(グーグルでさえ私に答えをくれません。)

4

3 に答える 3

2

構造体DataFileには、1 つのポインターと 1 つの整数が格納されます。ファイルに書き込むときは、文字列へのプログラム固有のポインターと整数を書き込みます。

それから読み取るときは、構造体にポインターと整数を再入力するだけです。これはDataFile.Name、おそらく初期化されていないメモリセグメントへのポインターになることを意味します。しかし、最初のハードコードされた文字列 ( "filename.txt") を指すファイルを作成したため、未定義ですが理解できる動作が発生し、この場合のポインターは、2 番目のプログラムで記述した最初のハードコードされた文字列を指します (この場合はError1)

本当にやりたいことは、実際の文字列をファイルに書き込むことです。

ホール書き込み構造を保持したい場合の簡単な解決策は、ポインターの代わりに配列を作成することです

typedef struct {
        char Name[512];
        int Index;
    } DataFile;

次に、データを初期化します

strncpy(DataTable[0].Name, "somefile.txt", sizeof(DataTable[0].Name) - 1); // just to make sure you dont overflow your array size
DataTable[0].Name[sizeof(DataTable[0].Name) - 1] = '\0';

行った方法でデータを再検討します。

于 2012-11-15T08:01:46.907 に答える
1

Achar*は単なるポインタ、つまり文字列を含む文字配列のアドレスです。文字列自体をファイルに書き込むことはありません。ファイルを読み取った後、同じ文字列がメモリ内の同じアドレスになくなるため、アプリケーションは失敗します。

文字列自体もファイルに保存する方法を考え出す必要があります。おそらく最初に長さを書き、次に内容を書きます。読み取り時に、長さ情報を使用してメモリを動的に割り当て、そのメモリに読み込むことができます。

于 2012-11-15T08:00:57.080 に答える
0

書き込みコードでは、 のストレージを割り当てていませんchar *Name。が指すメモリDataTable[0].Name = "somefile.txt"に実際にコピーしていない命令を実行すると、実際には、定数文字列を指す a 値が割り当てられます (さらに、文字列は右辺値であるため、ダングリング ポインターになります。経由でアドレス指定されるメモリ)。ファイル読み取りコードについても同様です。必要がある:"somefile.txt"NameName

  1. にストレージを割り当てますName
  2. memcpyまたは同様のものを使用して文字列を割り当てられたストレージにコピーします。
于 2012-11-15T08:00:42.360 に答える