2012-11-28 161 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