2015-01-26 86 views
1

我剛剛瞭解鏈接列表,我必須做一個包含很多部分的任務,但是我已經開始了,我需要做的第一件事是讀入一個輸入文件放入鏈表中。該文件的 部分是:將文本文件掃描到鏈接列表中

George Washington, 2345678 John Adams, 3456789 Thomas Jefferson, 4567890 James Madison, 0987654 James Monroe, 9876543 John Quincy Adams, 8765432

和共包含26行。

我現在要做的所有事情都只是在文件中讀取。 我嘗試通過使用這個代碼(在主現在)

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


struct node{ 

    char name[20]; 
    int id; 
    struct node *next; 

}*head; 



int main(void){ 

    struct node *temp; 
    temp = (struct node *)malloc(sizeof(struct node)); 
    head = temp; 

    FILE *ifp; 
    ifp = fopen("AssignmentOneInput.txt", "r"); 

    int c = 0; 

    while(c<26){ 
     fscanf(ifp, "%s", &temp->name); 
     fscanf(ifp, "%d", &temp->id); 
     printf("%d\n", c); 
     temp = temp->next; 
     c++; 
    } 

對於輸出,我知道的是,第一名字和所述第一ID被掃描,因爲系統c的值顯示爲0(此時我任意使用c的值來控制fscanf)。但之後,程序崩潰。所以問題必須與temp = temp->next;編譯好。

我對鏈表很新,所以我真的不知道自己在做什麼。

您的幫助表示感謝!

+0

你必須在每次循環時malloc一個新的節點,你必須設置前一個下一個指向新節點 – pm100 2015-01-26 21:29:01

+2

'fscanf(ifp,「%s」,&temp - > name);'會讀入「George」,而不是「George Washington」 – chux 2015-01-26 21:29:57

回答

1

首先,由於您正在編寫C,因此不需要投下malloc

其次,您必須自己爲每個新節點分配內存。第三,數組的名稱已經衰減到一個指針,所以你不應該拿它的&,因爲那樣你會得到一個指針,而不是你想要的。

最後,您需要修復您的scanf語法來處理字段中的空格。

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

#include <string.h> 

struct node{ 

    char name[20]; 
    int id; 
    struct node *next; 

}*head; 



int main(void){ 

    struct node *temp; 
    temp = malloc(sizeof(struct node)); 
    temp->next = NULL; 
    head = temp; 

    FILE *ifp; 
    ifp = fopen("AssignmentOneInput.txt", "r"); 

    int c = 0; 

    char buffer[1024]; 
    memset(buffer, 0, 1024); 
    while(c<5){ 
     fgets(buffer, 1024, ifp); 
     sscanf(buffer, "%19[^,], %d", temp->name, &temp->id); 
     printf("%d %s %d\n",c, temp->name, temp->id); 
     temp->next = malloc(sizeof(struct node)); 
     temp = temp->next; 
     temp->next = NULL; 
     c++; 
    } 
} 
1

在以下幾行你已經分配了足夠的空間,爲您的列表(一個struct node)的單個元素,並指出您head指針指向它:

temp = (struct node *)malloc(sizeof(struct node)); 
head = temp; 

後來你值讀入此元素的nameid領域:

fscanf(ifp, "%s", &temp->name); 
fscanf(ifp, "%d", &temp->id); 

但什麼是temp->next點?您迄今爲止只爲單個元素分配空間。當您將其添加到列表中時,您需要爲每個後續元素分配空間。

編輯:作爲@ merlin2011下面指出,這個答案只會幫助你解決程序崩潰,但不會完全讓你的程序正常工作。但是,希望一旦它沒有崩潰,你將能夠更好地進行調試。

+0

啊謝謝你的幫助! – akomega 2015-01-26 21:31:57

+1

這個回答解決了內存問題,但不足以使代碼根據需要工作。 – merlin2011 2015-01-26 21:33:53

+0

@ merlin2011 - 的確如此。由於這顯然是一項學校任務,我選擇只是解決眼前的問題,並希望它能讓OP取得進展。我會盡量在答案中註明。 – Squirrel 2015-01-26 21:49:37

1

主要問題肯定是temp = temp->next將temp設置爲字段next這是從未初始化的,導致代碼分段。下一個循環出現故障。

存在鏈接列表問題和輸入問題。建議在找到好數據之前不要分配空間。

temp_head開頭。代碼僅使用next字段temp_head

struct node temp_head; 
temp_head.next = NULL; 
struct node *p = &temp_head; 

每當代碼讀取線數據,推薦使用fgets()讀取,然後掃描緩衝區。

char buf[100]; 
while (fgets(buf, sizeof buf, ifp) != NULL) { 
    struct node nbuf; 

使用sscanf()掃描緩衝區。使用'%[^,]'來閱讀,直到','

if (2 != sscanf(buf, " %19[^,],%d", nbuf.name, &nbuf.id)) { 
    break; // Invalid data encountered 
    } 
    nbuf.next = NULL; 

    // Code does not allocate data until good data was found 
    p->next = malloc(sizeof *(p->next)); 
    if (p->next == NULL) break; // OOM 
    p = p->next; 
    *p = nbuf; // Copy the data 
} 

head = temp_head.next; 

注:

不需要在temp = (struct node *)malloc(sizeof(struct node));演員。

考慮這種分配方式:temp = malloc(sizeof *temp),IMO代碼更簡單,維護更少。

fscanf(ifp, "%s", &temp->name); fscanf(ifp, "%d", &temp->id);有3個問題:對字符串輸入沒有限制,不需要&以及未能檢查掃描結果。上面的代碼通知使用(2 != sscanf(buf, " %19[^,], %d", nbuf.name, &nbuf.id),這限制了字符串輸入到19 char(留有餘地終止'\0',當字段是一個數組不使用&,並且檢查該2個字段被成功掃描。

結束之前main(),代碼應該釋放已分配的數據。

+0

對於OP的問題並不是無關緊要的嗎? – 2015-01-26 21:35:49

+0

@Peter Schneider OP的掃描和LL問題捆綁在一起。 – chux 2015-01-26 21:50:46

+0

他們是如何綁定的? – 2015-01-26 22:00:12