如何删除C语言中从drivers.txt加载的链表里指定车队的车手节点
链表删除指定车队节点实现方案
现有代码已知问题
- 加载函数
drivers_load中,重置索引i=0的逻辑写在case 2的break之后,永远不会执行,导致无法正确读取多个车手数据 - 打印函数
drivers_print中结构体成员引用错误,定义的是name/team,代码中错误写为presenter/birth_number - 删除函数存在核心逻辑错误:
- 未处理头节点即为待删除节点的场景,传入一级指针无法将修改后的头节点返回给调用方
- 遍历未记录前驱节点,无法正确修改链表关联关系
- 删除逻辑固定操作头节点的后继节点,和实际匹配到的待删节点无关
- 未释放
name/team指向的堆内存,存在内存泄漏 - 使用了未定义的类型
node_t
实现思路
- 删除函数采用返回新头节点的方式处理头节点被删除的场景
- 遍历链表同时记录当前节点和前驱节点
- 匹配到待删除节点时:
- 若为头节点,直接将头指针后移
- 若为普通节点,将前驱节点的next指向当前节点的next
- 依次释放当前节点的
name、team内存,再释放节点本身
修复后代码
删除函数实现
drivers_t* node_delete(drivers_t *head, const char* target_team) { drivers_t *curr = head; drivers_t *prev = NULL; // 适配fgets读取内容自带换行的格式 char team_with_newline[32] = {0}; strcpy(team_with_newline, target_team); strcat(team_with_newline, "\n"); while (curr != NULL) { if (strcmp(curr->team, team_with_newline) == 0) { // 待删节点是头节点 if (prev == NULL) { head = curr->next; } else { prev->next = curr->next; } // 释放内存避免泄漏 free(curr->name); free(curr->team); drivers_t *temp = curr; curr = curr->next; free(temp); } else { prev = curr; curr = curr->next; } } return head; }
调用示例
// 加载链表 drivers_t *head = drivers_load("drivers.txt"); // 删除RedBull车队的所有车手 head = node_delete(head, "RedBull"); // 打印处理后的链表 drivers_print(head);
修正后的打印函数
void drivers_print(drivers_t *head){ int number = 1; for (drivers_t *curr = head; curr != NULL; curr = curr->next){ printf("%d.\n", number++); printf("Driver: %s", curr->name); printf("Team: %s", curr->team); } }
修正后的加载函数
drivers_t *drivers_load(const char *file){ int i = 0; FILE *fp = fopen(file, "r"); if (!fp) return NULL; drivers_t *ptr = NULL; drivers_t *head = NULL; char buffer[255]; while (fgets(buffer, 255, fp) != NULL){ switch(i++){ case 0: if( !ptr ) { ptr = drivers_new(); head = ptr; } else { ptr->next = drivers_new(); ptr = ptr->next; } break; case 1: ptr->name = strdup(buffer); break; case 2: ptr->team = strdup(buffer); i = 0; break; } } fclose(fp); return head; }
内容的提问来源于stack exchange,提问作者Erri000
相关产品推荐
相关产品推荐

