C-链表-插入元素未更新-仅添加最后一个输入元素
前言:目标是提示用户输入,将每个元素(输入行)添加到链接列表中C-链表-插入元素未更新-仅添加最后一个输入元素,c,linked-list,C,Linked List,前言:目标是提示用户输入,将每个元素(输入行)添加到链接列表中 char command[120]; int counter = 0; while(counter < 3) { printf("Enter element: "); fgets((void *)command, sizeof(command), stdin); push(test_list, command); //Insert counter++; } 我一直在使用中的一些示例代码,其
char command[120];
int counter = 0;
while(counter < 3) {
printf("Enter element: ");
fgets((void *)command, sizeof(command), stdin);
push(test_list, command); //Insert
counter++;
}
我一直在使用中的一些示例代码,其中显示了一个链表示例。
我修改了代码,使其采用“字符串”而不是整数
我的插入功能如下所示:
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;
}
}
node_t * test_list = malloc(sizeof(node_t));
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;
}
}
现在,我主要提出以下清单:
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;
}
}
node_t * test_list = malloc(sizeof(node_t));
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;
}
}
通过以下方式添加元素:
push(test_list, "FOO");
push(test_list, "FEE");
push(test_list, "FAA");
打印列表时,使用打印列表(测试列表),我得到以下输出:
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++;
}
该列表打印为:
FOO
FEE
FAA
Sweden
Sweden
Sweden
编辑(添加打印功能)
我的打印功能如下所示:
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;
}
}
node_t * test_list = malloc(sizeof(node_t));
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;
}
}
我遗漏了什么,或者:我如何修复这个问题?非常感谢您的帮助 您有一个容量为120的数组
命令
。您可以使用它来读取值。这没关系
然后发送指向要存储的数组的指针。它被储存起来了,一切都很好
下次读取输入时,将其读取到同一数组,并为该数组指定要存储的指针。因此,您正在更改指针指向的内存内容。这不好
您需要为每个字符串分配单独的内存区域,并处理它们的释放strdup
是获取包含用户输入内容的新内存块的最简单方法
但请记住,当您不再需要内存时,您确实必须释放内存。在这种情况下,您可能永远不会删除任何字符串,但删除时,您不能只删除元素,还必须释放字符串使用的内存。
current->data=data代码>此处仅复制指针地址而不是数据,在该地址(“命令”地址)上,最后一个数据(“瑞典”)将可用。
您应该使用strcpy(当前->数据,数据)
来复制数据。使用strdup
来返回堆上分配的字符串的副本
函数的作用是:返回一个指向新字符串的指针,该字符串是字符串s的副本。新字符串的内存由malloc(3)获得,可用free(3)释放
node_t*test_list=malloc(sizeof(node_t));
测试列表->下一步=空;
测试列表->数据=NULL;
while(计数器<3){
printf(“输入元素:”);
fgets((void*)命令、sizeof(命令)、stdin);
push(test_list,strdup(command));//插入
计数器++;
}
我认为您应该使用strcpy复制城市名称,在这种情况下,使用指针指向城市名称可能不起作用。node_t*test_list=malloc(sizeof(node_t));测试列表->数据=NULL代码>推送(测试列表,标准(“FAA”);push(测试列表、strdup(命令))代码>如果您在将“命令”字符串推送到列表之前打印它,那么您将看到您实际推送的内容,并确保得到您想要的内容,因为它在循环外部工作。调试器、记录器………@northerner您可以发布您的打印方法吗?我想这就是问题所在,谢谢你。有没有关于如何做到这一点的建议?发现内存分配很混乱。@Northern它看起来像是一个很难的主题。您应该阅读这方面的最佳实践,但一种开始的方法是思考谁“拥有”数据。在这种情况下,您可以假设列表“拥有”字符串,因此当从列表中删除元素时,列表节点和字符串都将是自由的。但请注意,之后不能有任何指向该节点或字符串的指针。这很公平。但是,为什么代码可以处理单独的push调用,比如push(test_list,“Hello”)和push(test_list,“Bye”)?为什么这些像HELLO-BYE而不是BYE-BYE一样存储@北方人,因为它们是由不同指针指向的独立内存区域。如果您要执行strcpy(命令“Hello”);推送(测试列表、命令);strcpy(命令,“再见”);推送(测试列表、命令)代码>您将得到两次再见,因为您正在重用相同的内存区域。