2012-11-28 164 views
2

我目前正在试图写入和读取一个简单的链接列表到一个文件中,但它似乎并没有真正的工作,我不知道如果它甚至是可能的。C指针,结构和fwrite

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 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; 
} 
+0

“fread(curr)'而不是'fread(&curr)'就足够了。另外要注意指针,因为'next'在写入和读回之后会受到影响。 – foxx1337

+0

@ foxx1337:'curr'是一个野生指针,所以虽然你是正确的解除引用,但它仍然不起作用。 –

回答

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; 
} 
3

curr是一个未初始化指针(一个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); 

在两种情况下,currFLUG*和指向存储FLUG的有效内存,因此您需要阅读sizeof(FLUG),而不是sizeof(FLUG*)。任何类型的指针的典型大小是4或8个字节。在我的x86盒子上,它是4个字节,而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的地址传递到fread()FLUG**被传递给fread()这是不正确。

+0

但是,如何将FLUG结构放入指针中并以其他方式进入?这甚至有可能吗? – OhSnap

+0

@ user854699,我不明白你的意思。 – hmjd

+0

我有一个指针,我用它来浏览列表。正如你们所说,我不能把这些指针放到文件中。我需要加入结构,但是如何将指针转换为结构? – OhSnap

2

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

另一个问题是,你不应该写指针到文件;数据仅在您的流程中有意义。当你回读FLUG时,至少应该把cur->放在合理的位置(比如下一个FLUG!)。

0

您正在写一个指向文件的指针,称为浅拷贝。指针不可转让,你需要编写代码来做深拷贝。要么,要么使用类似JSON或YAML的东西。

+0

嗯..我会采取深拷贝的方式,但我不知道如何做到这一点。如何将指针中的值转换为结构体? – OhSnap

+0

您需要为每个值分配一个内存缓冲区并专门复制它们,然后写入缓冲区。很明显,您需要一个文件结构才能识别每个组件。在读入时,您需要将每个值读回到准备好的内存区域,因此您可能还需要存储每个组件的大小。很多工作! JSON和YAML为你做了所有的事情,但作为文本(所以他们可以慢)。 – cdarke

+0

我不能这样做,因为这是我必须为大学做的事情。没有使用extern资源的情况下没有办法保存这些数据吗? – OhSnap