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;

我担心问题可能是我不仅在写字符,而且在写 int .. 尤其是枚举。

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 时出现错误。

好的,所以我稍微改变了这两个功能,但它似乎仍然不起作用。对不起,我好像没听懂……

[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

就个人而言,当指针为typedefd 时,我发现它非常令人困惑,因为在使用时变量是指针并不明显:

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);

在这两种情况下,curris aFLUG*并且指向用于存储 a 的有效内存,FLUG因此您需要读取sizeof(FLUG),而不是sizeof(FLUG*). 任何类型的指针的典型大小是 4 或 8 个字节。在我的 x86 机器上,它是 4 个字节,a 的大小FLUG是 88 个字节。两者的size参数fwrite()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. */

&curr传递to的地址fread()意味着FLUG**正在传递的 afread()是不正确的。

于 2012-11-28T09:16:58.710 回答
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 回答
2

哇!想想你在读什么记忆。您fread要求将数据转储到某个随机位置(因为 curr 未初始化,因此指向您的进程中可能不存在的内存)。您需要分配一些 FLUG 并读入它们。

另一个问题是你不应该写指向文件的指针。数据仅在您的流程中有意义。当你读回 FLUG 时,至少,你应该将 cur->next 设置为一些有意义的东西(比如下一个 FLUG!)。

于 2012-11-28T09:17:42.970 回答
0

您正在编写指向文件的指针,称为浅拷贝。指针不可转移,需要编写代码进行深拷贝。要么,要么使用 JSON 或 YAML 之类的东西。

于 2012-11-28T09:18:07.740 回答