从链表中删除一个节点
Posted
技术标签:
【中文标题】从链表中删除一个节点【英文标题】:Deleting a node from linked list 【发布时间】:2022-01-11 20:47:38 【问题描述】:我正在尝试删除按出生编号给出的节点,例如 9403133410。下次我打印链接列表时,我只想在输出中看到 Mike。
这是我要加载到链表中的 file.txt
***
Dave
9403133410
***
Mike
9458133410
***
Dave
9403133410
这是我的名为 node_t 的结构:
typedef struct node
char *presenter;
char *birth_number;
struct node *next;
node_t;
node_t *node_new()
node_t *node = malloc(sizeof(node_t));
node->next = NULL;
node->presenter = NULL;
node->birth_number = NULL;
return node;
这是我的加载函数
node_t *node_load(const char *file)
int counter = 0, number_entries = 0, db_loaded = 0;
char buffer[BUFFER_SIZE];
dbFile = fopen(DATABASE_FILE, "r");
if (!dbFile)printf("Zaznamy neboli najdene!\n");
node_t *ptr = NULL, *head = NULL;
while(fgets(buffer, BUFFER_SIZE, dbFile) != NULL)
switch(counter++)
case 0:
if (!ptr)
ptr = node_new();
head = ptr;
else
ptr->next = node_new();
ptr = ptr->next;
number_entries++;
break;
case 1:
ptr->presenter = strdup(buffer);
break;
case 2:
ptr->birth_number = strdup(buffer);
counter = 0;
break;
fclose(dbFile);
return head;
这是我的删除节点功能:
void node_delete(node_t *head)
node_t *temp, *previous;
temp = head;
char birth_n[14];
scanf("%s", &birth_n);
strcat(birth_n, "\n");
for ( ; temp->next != NULL; temp = temp->next)
if (strcmp(birth_n, temp->birth_number) == 0)
if (temp == head)
head = temp->next;
else
previous = temp;
previous->next = temp->next;
free(temp);
所以我正在尝试删除其出生编号给出的节点。
调试功能:
void node_delete(node_t *head)
node_t *temp, *previous;
previous = temp = head;
char birth_n[14];
scanf("%s", &birth_n);
if (strcmp(birth_n, temp->birth_number) != 0)
head = head->next;
free(temp);
这个函数应该删除第一个节点,但它不会删除它...
【问题讨论】:
请出示minimal reproducible examplescanf("%s", birth_n);
为自己创建一个minimal reproducible example,并将输入逻辑与链表逻辑分开。马虎的编程导致菜鸟错误。
请edit您的问题并创建一个minimal reproducible example,即我们可以编译和运行的程序与输入(如果需要)、实际和预期输出一起重现问题。我建议添加一个 main 函数,该函数创建一个带有硬编码数据的链表并调用您的函数 node_delete
。你为值birth_n
输入了什么?如果您输入12.03.2021
或03/12/2021
之类的内容,则数组大小会太小。 \n
和 \0
需要另外两个字符。
没有阅读问题,我敢打赌,从没有return
或**
参数的链接列表中删除无法可靠地工作,正因为如此。
我编辑了问题
【参考方案1】:
函数没有意义。
首先将搜索到的字符串通过参数传递给函数。
其次,该函数处理指向头节点的指针值的副本。更改函数内的副本不会影响用作函数参数的原始指针。
至少不是这个电话
scanf("%s", &birth_n);
你应该写
scanf("%13s", birth_n);
还不清楚您为什么要尝试附加换行符'\n'
strcat(birth_n, "\n");
这个for循环
for ( ; temp->next != NULL; temp = temp->next)
可以在传递的指针是空指针时调用未定义的行为。即使该节点包含目标字符串,当列表仅包含一个节点时,也会跳过循环。
此外,当删除带有目标字符串的节点时,循环不会终止。
并在循环的第三个表达式中使用指针 temp
temp = temp->next
在这句话之后
free(temp);
调用未定义的行为。
函数可以如下所示
int node_delete( node_t **head, const char *birth_number )
while ( *head != NULL && strcmp( ( *head )->birth_number, birth_number ) != 0 )
head = &( *head )->next;
int success = *head != NULL;
if ( success )
node_t *temp = *head;
*head = ( *head )->next;
free( temp );
return success;
在 main 中,您必须输入将要搜索的目标字符串,并且至少像调用函数一样
node_delete( &head, birth_number );
您也可以检查函数的返回值,以确定是否删除了具有指定字符串的节点。
【讨论】:
谢谢,但它不起作用我尝试了一些新的东西,你能看看吗?我更新了问题......该函数应该删除第一个节点但它不会删除它,而是给出奇怪的符号 @Erri000 你错了。显示的功能有效。不起作用的是您自己的代码与提供的函数没有任何共同之处。 正如你所建议的,我尝试了它,但没有将 & 放入 scanf 并且没有 strcat,但是比较它没有它就无法工作...... @Erri000 听着你知道你在存储什么字符串吗?! 一点点,我是新手,但我只是告诉你,没有 strcat 它不起作用我不知道为什么......【参考方案2】:如果您启用编译器警告并将警告视为错误,您可能会看到如下错误消息:
format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[14]’ [-Werror=format=]
| scanf("%s", &birth_n);
| ~^ ~~~~~~~~
| | |
| | char (*)[14]
| char *
这告诉您scanf
的%s
格式字符串与您输入的内容不兼容。您正在向它提供一个指向字符指针的指针,而不仅仅是您明确想要的字符指针。
您应该只将 birth_n
传递给 scanf
函数,如下所示:
scanf("%s", birth_n);
这与链表无关,而是 C 中的基本输入和字符串处理。
【讨论】:
问题是当我想 strcmp 没有 scanf("%s", &birthnumber) 和 strcat() 它不返回零。以上是关于从链表中删除一个节点的主要内容,如果未能解决你的问题,请参考以下文章