2

現在、単純なリンクリストをファイルに読み書きしようとしていますが、実際には機能していないようで、可能かどうかもわかりません。

typedef struct flug
{
    int            flugnummer;
    char            flugziel[50];
    enum TAG        flugtag;
    int            flugzeit_stunde;
    int            flugzeit_minute;
    int            gateway;
    char            status[10];
    struct flug    *next;
}FLUG;

typedef FLUG *ELEM_ZGR;

問題は、私が char だけでなく int .. と特に enum も書いていることにあるのではないかと心配しています。

int fluege_sichern() {
ELEM_ZGR curr;

FILE *fp;
char* tag;

curr = first;

if (fopen_s(&fp, datei,"a+b") != 0) {
    printf("\nDatei %s nicht zum Anhaengen zu oeffnen",datei);
    PAUSE;
    exit(1);
}

for(curr = first; curr != NULL; curr = curr->next) {
    fwrite(curr, sizeof(FLUG), 1, fp);
}

    fclose(fp);
    return 1;
}

これは、要素をバイナリとしてファイルに書き込む関数であると想定されています。この関数でエラーは発生しません。

void fluege_laden() {
ELEM_ZGR curr;
FILE *fp;
int i = 0;

if (fopen_s(&fp, datei,"rb") != 0) {
    printf("\nDatei %s nicht zum Lesen zu oeffnen",datei);
    PAUSE;
    exit(1);
}

while(1) {
     fread(&curr, sizeof(FLUG), 1, fp);
     printf("\n%d", curr->flugnummer);
     //fluege_sortieren(curr);
}
}

curr->flugnummer を印刷しようとすると、エラーが発生します。

わかりましたので、2 つの関数を少し変更しましたが、まだ機能していないようです。すみません、よくわからないようです…

[EDIT2] 動作しない別のバージョン:

void fluege_laden() {
    ELEM_ZGR curr;  // <<<- allocate an actual struct here rather than just a pointer
    FILE *fp;

    int i = 0;
    curr = first;

    if (fopen_s(&fp, datei,"rb") != 0) {
        printf("\nDatei %s nicht zum Lesen zu oeffnen",datei);
        PAUSE;
        exit(1);
    }

    while(1) {
        fread(curr, sizeof(FLUG), 1, fp);
        printf("\n%d", curr->flugnummer);   // <<<
        printf("\n%s", curr->flugziel);
        //fluege_sortieren(curr);
        PAUSE;
    }

}

int fluege_sichern() {
ELEM_ZGR curr;
FILE *fp;

curr = first;

if (fopen_s(&fp, datei,"a+b") != 0) {
    printf("\nDatei %s nicht zum Anhaengen zu oeffnen",datei);
    PAUSE;
    exit(1);
}

for(curr = first; curr != NULL; curr = curr->next) {
    fwrite(curr, sizeof(FLUG), 1, fp);
}

    fclose(fp);
    return 1;
}
4

4 に答える 4

3

currは初期化されていないポインタ (a ) であるため、が呼び出されたFLUG*ときに有効なメモリを指していません。fread()無効なメモリへの書き込みは未定義の動作です (プログラムがエラーをセグメント化するか、正しく実行されないか、最悪の場合は正しく実行される可能性があります)。スタック割り当てオブジェクト (タイプFLUG) を作成するか、動的にメモリを割り当てますcurr

typedef個人的には、使用時に変数がポインターであることが明らかではないため、ポインターが d の場合は非常に混乱します。

ELEM_ZGR curr;

以下は明確です。

FLUG* curr; /* Or just 'FLUG curr;' for this case. */

の結果をチェックしてfread()、プログラムが古いデータで動作していないことを確認します。

FLUG curr;
while (1 == fread((&curr, sizeof(FLUG), 1, fp))
{
    printf("\n%d", curr.flugnummer);
}

(質問の編集に応じて)

つまり、次のように変更します。

fwrite(curr, sizeof(FLUG*), 1, fp);
fread(&curr, sizeof(FLUG*), 1, fp);

に:

fwrite(curr, sizeof(FLUG), 1, fp);
fread(curr, sizeof(FLUG), 1, fp);

どちらの場合も、currは でFLUG*あり、 は を格納するための有効なメモリを指しているため、ではなくFLUGを読み取る必要があります。あらゆるタイプのポインターの一般的なサイズは、4 または 8 バイトです。私の x86 ボックスでは 4 バイトで、a のサイズは 88 バイトです。both andの引数は、読み書きするバイト数を指示します。sizeof(FLUG)sizeof(FLUG*)FLUGsizefwrite()fread()

fwrite(curr, sizeof(FLUG), 1, fp); /* write 88 bytes to fp from address curr. */
fread(curr, sizeof(FLUG), 1, fp); /* read 88 bytes from fp and write to the
                                     address beginning at curr. */

&currtoのアドレスを渡すということは、間違ったto に渡されていることをfread()意味します。FLUG**fread()

于 2012-11-28T09:16:58.710 に答える
2

うわあ!そこに読み込んでいるメモリを考えてください。データをランダムな場所にダンプするように求めています( currfreadは初期化されていないため、おそらくプロセスに存在しないメモリを指しています)。いくつかの FLUG を割り当てて読み込む必要があります。

もう 1 つの問題は、ファイルへのポインターを書き込むべきではないということです。データはプロセス内でのみ意味を持ちます。FLUG を読み返すときは、少なくとも、cur->next を適切なもの (次の FLUG など) に設定する必要があります。

于 2012-11-28T09:17:42.970 に答える
2

読み取りルーチンELEM_ZGR curr;には、初期化されていないポインターがあります。次のようなことをする必要があります:

void fluege_laden() {
    FLUG curr;  // <<<- allocate an actual struct here rather than just a pointer
    FILE *fp;
    int i = 0;

    if (fopen_s(&fp, datei,"rb") != 0) {
        printf("\nDatei %s nicht zum Lesen zu oeffnen",datei);
        PAUSE;
        exit(1);
    }

    while(1) {
        fread(&curr, sizeof(FLUG), 1, fp); // <<<
        printf("\n%d", curr.flugnummer);   // <<<
        //fluege_sortieren(curr);
    }
}

また、書き込みルーチンでは、構造体全体を書き込む必要があります。

int fluege_sichern() {
    ELEM_ZGR curr;
    FILE *fp;
    char* tag;

    curr = first;

    if (fopen_s(&fp, datei,"a+b") != 0) {
        printf("\nDatei %s nicht zum Anhaengen zu oeffnen",datei);
        PAUSE;
        exit(1);
    }

    for(curr = first; curr != NULL; curr = curr->next) {
        fwrite(curr, sizeof(FLUG), 1, fp); // <<<- curr is already a pointer - do not dereference here !
    }

    fclose(fp);
    return 1;
}
于 2012-11-28T09:16:35.917 に答える
0

浅いコピーと呼ばれるファイルへのポインターを書き込んでいます。ポインタは転送できません。ディープ コピーを実行するにはコードを記述する必要があります。それか、JSON や YAML のようなものを使用してください。

于 2012-11-28T09:18:07.740 に答える