2015-10-30 23 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)来复制数据。