2014-09-23 33 views
-2

我試圖創建一個程序,用下面的格式的文本文件中讀取:我的鏈表程序將無法正常工作

Smith, John  
Johnson, Harry  
Clark, David 

(這可以無休止地繼續下去,有沒有需要在每個名稱之間的空行,我只是爲了清晰起見而這樣寫的)

該文本文件的每一行都包含:last name,first name。鏈表應該存儲每個名字和姓氏作爲名字節點。但是,我相信我的總體架構應該能夠工作,但是,隨着程序的執行,似乎像pCurrentpHead這樣的變量正在被重新調整而不會被重新分配。我留下了一個亂七八糟的鏈表,我從來沒有見過這樣的事情。任何人都可以發現我的架構或其他任何可能導致此程序無法按預期工作的缺陷。由於

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

#include <string.h> 

struct nameNode { 
    char* first; 
    char* last; 
    struct nameNode* pNext; 
    struct nameNode* pPrev; 
}; 

struct nameNode* pHead, *pLast; 
char firstName[50], lastName[50]; 

void insert_end(char* first, char* last) { 
    struct nameNode* var = NULL, *temp = NULL; 

    var = (struct nameNode*)malloc(sizeof(struct nameNode)); 

    var->first = first; 
    var->last = last; 
    if (pHead == NULL) { 
     pHead = var; 
     pHead->pPrev = NULL; 
     pHead->pNext = NULL; 
     pLast = pHead; 
    } else { 
     pLast = pHead; 
     while (pLast != NULL) { 
      temp = pLast; 
      pLast = pLast->pNext; 
     } 

     pLast = var; 
     temp->pNext = pLast; 
     pLast->pPrev = temp; 
     pLast->pNext = NULL; 
     printf("Phead is %s\n", pHead); 
    } 
} 

int main() { 
    char file[100]; 
    printf("Enter input file "); 
    scanf("%s", file); 
    FILE* in_file = fopen(file, "r"); 

    while (fscanf(in_file, "%s %s", lastName, firstName) != EOF) { 
     insert_end(lastName, firstName); 
    } 
} 
+0

此問題似乎是無關緊要的,因爲它不會創建最小,完整和可驗證示例。 – haccks 2014-09-23 21:05:35

+1

將這三個名稱複製到文本文件中,然後在出現提示時編寫地址並檢查鏈接列表。這是一個完整的例子,對嗎?另外,我還可以添加一條打印語句來告訴程序員,如果這將有助於問題變得更加明顯,那麼pHead與while循環的每次迭代是否相等? – user3451026 2014-09-23 21:09:38

回答

0

你念你的名字變成了一個全局變量和商店,你在閱讀它的地址。然後,您將新名稱讀入同一個變量 - 因此您再次存儲相同的地址。

變化這在insert_end代碼

var->first = strdup (first); 
var->last = strdup (last); 

存儲副本讀入firstNamelastName琴絃


小:因爲它是,你實際上有未定義行爲。你檢查是否pHead是NULL,但你永遠不會初始化它。請務必將其設置爲NULL調用insert_end之前,或者簡單地將其初始化爲

struct nameNode* pHead = NULL, *pLast = NULL; 

而且未成年人:添加節點沒有temp可以做下面的方式。實際上,您不需要循環,因爲您已經知道pLast指向列表的末尾 - 但如果您想確保它是有效的,則可以利用這樣一個事實:對於最後的nameNode其成員pNext必須爲NULL:

pLast = pHead; 
while (pLast->pNext != NULL) { 
    pLast = pLast->pNext; 
} 
pLast->pNext = var; 
pLast->pNext->pPrev = pLast; 
pLast->pNext->pNext = NULL; 
pLast = pLast->pNext; 

還未成年人:擺脫逗號,在insert_node插入此附近展開:

if (first && first[0] && first[strlen(first)-1] == ',') 
    first[strlen(first)-1] = 0; 

注意,這將刪除名爲參數逗號first,這實際上是最後一個名字。您可能想要在整個代碼中糾正這些問題。

也很輕微:您的scanf是不是非常安全或錯誤恢復。它可以讀取每個字符串(49個字符)的存儲空間之外的內容,並且您正在檢查文件結尾,但不是參數計數不匹配。

這應該會更好:

while (fscanf(in_file, " %49[^,],%49s", lastName, firstName) == 2) { 
    insert_end(lastName, firstName); 
} 

- 作爲一個額外的好處,它也讀出,當時忽略了逗號。

+0

救生員,非常感謝。所以回顧一下,問題是一個變量範圍的東西? – user3451026 2014-09-23 22:17:13

+0

是的,這是主要的(雖然我不會稱之爲「範圍」)。請務必閱讀我的小調。 – usr2564301 2014-09-23 22:18:50

0

我相信你需要定義你的NameNode結構如下:

struct nameNode { 
    char[some_size] first; 
    char[some_size] last; 
    struct nameNode* pNext; 
    struct nameNode* pPrev; 
}; 

或者malloc的第一個和最後一個當插入節點空間。

+0

這本身並沒有解決它,儘管它*可以*。您可能想要指出需要進行哪些其他更改。 – usr2564301 2014-09-23 22:20:13