2015-10-30 21 views
1

前言:目標是提示輸入的用戶,添加各元素(輸入線)轉換成一個鏈表。Ç - 鏈表 - 插入元件不更新 - 僅加入最後一個輸入元件

我一直在玩弄從Learn-C.org一些示例代碼,它顯示了一個鏈表的例子。 我修改了代碼,以便它使用「字符串」而不是整數。

插入功能如下:

void push(node_t * head, char *data) { 
    node_t * current = head; 

    if(head == NULL) { 
     printf("First element ever!\n"); 
    } 
    else if(current->data == NULL) { 
     current->data = data; 
     current->next = NULL; 

    } 
    else { 
     while (current->next != NULL) { 
     current = current->next; 
     } 
     current->next = malloc(sizeof(node_t)); 
     current->next->data = data; 
     current->next->next = NULL; 
    } 
} 

現在,在主,我發起名單如下:

push(test_list, "FOO"); 
    push(test_list, "FEE"); 
    push(test_list, "FAA"); 

node_t * test_list = malloc(sizeof(node_t)); 

添加元素與實現

打印清單時,使用print_list(test_list),我得到下面的輸出:

FOO 
FEE 
FAA 

問題

不過,我則包括一個while循環,提示用戶輸入和其加入到鏈表。

char command[120]; 
int counter = 0; 
while(counter < 3) { 
    printf("Enter element: "); 
    fgets((void *)command, sizeof(command), stdin); 
    push(test_list, command); //Insert 
    counter++; 
} 

但是,這不會將每個元素添加到鏈接列表中。相反,它將LAST元素添加到列表中三次。

例如,當提供:

Enter element: Argentina 
Enter element: Mexico 
Enter element: Sweden 

將打印列表爲:

FOO 
FEE 
FAA 
Sweden 
Sweden 
Sweden 

編輯(添加打印功能)

打印功能如下:

void print_list(node_t * head) { 
    node_t * current = head; 

    printf("**** Printing list ****\n"); 
    while (current != NULL) { 
     printf("%s\n", current->data); 
     current = current->next; 
    } 
} 

我缺少什麼,還或者:我怎樣才能解決這個問題?任何幫助,高度讚賞。

+5

我認爲你應該使用'strcpy'複製的城市名稱,使用指針可能無法在這種情況下工作,給他們指引。 – ameyCU

+1

'node_t * test_list = malloc的(的sizeof(node_t)); test_list->數據= NULL;'...'推(test_list,的strdup( 「FAA」));推(test_list,的strdup(命令));' – BLUEPIXY

+0

如果你在推送到列表之前先打印「命令」字符串,那麼你會看到你實際推送的內容,並確保你得到你想要的內容,因爲它在循環之外工作。 –

回答

2

使用strdup返回堆上分配的字符串的副本。

strdup()函數返回一個指向新字符串的指針,該字符串是字符串s的副本。使用malloc(3)獲得新字符串的內存,並且可以使用free(3)釋放內存。

node_t *test_list = malloc(sizeof(node_t)); 
test_list->next = NULL; 
test_list->data = NULL; 
while(counter < 3) { 
    printf("Enter element: "); 
    fgets((void *)command, sizeof(command), stdin); 
    push(test_list, strdup(command)); //Insert 
    counter++; 
} 
0

您有一個數組command與120使用該值在閱讀能力。還行吧。

然後你發送一個指針來存儲這個數組。它被儲存起來,一切都很好。

你讀輸入下一次,則讀給相同的數組,針對你給要存儲的指針。所以你正在改變那個指針指向的內存的內容。這不好。

您需要分配單獨的存儲區域每串並處理他們的解除分配。 strdup是獲取用戶輸入內容的新內存塊的最簡單方法。

但是千萬記住,你真的要解除分配內存時,你不需要它了。在這種情況下,你可能永遠不會刪除任何字符串,但是當你這樣做時,你不能刪除元素,你還必須釋放字符串使用的內存。

+0

謝謝。如何做到這一點的任何指針?查找內存分配相當混亂。 – northerner

+0

@northerner它看起來像它,它是一個很難的主題。您應該閱讀關於這方面的最佳實踐,但開始的一種方法是認爲誰擁有數據。在這種情況下,你可以假定列表「擁有」字符串,所以當一個元素從列表中移除時,列表節點和字符串都將是'free'd。但請注意,你*不能*有任何指針指向該節點或字符串後。 –

+0

夠公平的。然而,爲什麼代碼與個別調用一起工作,例如push(test_list,「Hello」)和push(test_list,「Bye」)? 爲什麼這些存儲如HELLO - BYE而不是BYE - BYE。 ? – northerner

0

current->data = data;在這裏你只複製指針地址沒有數據,該地址(的「命令」地址)最後的數據(「瑞典」)將可用。 您應該使用strcpy(current->data,data)來複制數據。