[英]Deleting a user-entered string node from a linked list
我正在编写一个 function,它应该从学生的链接列表中删除用户选择的节点。 该程序将通过 read_line function 获取用户输入的学生姓名、姓氏和 email,然后 1) 定位具有这些元素的节点,2) 绕过该节点,以及 3) 释放该节点占用的 memory。 我的function会删除除头节点以外的任何节点,我无法理解我的逻辑是否有错误。
这是我的 function 代码:
struct student* remove_from_list(struct student *list){
struct student *p;
struct student *cur;
struct student *delete = malloc(sizeof(struct student));
if(delete == NULL){
printf("\nMalloc failed. \n");
}
if(list==NULL){
printf("\nRoster empty. Nothing to remove.\n");
return list;
}
printf("Enter the last name of the student to be removed: ");
read_line(delete->last, NAME_LEN);
printf("Enter the first name of the student to be removed: ");
read_line(delete->first, NAME_LEN);
printf("Enter the email of the student to be removed: ");
read_line(delete->email, EMAIL_LEN);
//to check if student is in the list
for(p=list; p!=NULL; p=p->next){
if(((strcmp(delete->last, p->last))!=0) || (strcmp(delete->first,p->first)!=0)
|| (strcmp(delete->email, p->email)!=0)){
continue;
}
else{
break;
}
printf("\nThis student does not exist.\n");
return list;
}
//to remove any element other than first
for(cur=list; cur->next!= NULL; cur=cur->next){
if(strcmp(cur->next->last, delete->last)==0 &&
strcmp(cur->next->email,delete->email)==0 &&
strcmp(cur->next->first, delete->first)==0){
delete=cur->next;
cur->next = cur->next->next;
free(delete);
printf("\nStudent has been removed from the list.\n");
return list;
}
}
cur=list; //to remove first element
if(cur->next == NULL){
cur=cur->next;
free(delete);
printf("\nStudent has been removed from the list.\n");
return list;
}
}
我的 function 没有删除头节点,我不确定这是一个小修复,还是我的逻辑有根本性的错误。 我已经看到使用 integer 输入执行此操作的示例,但在我的案例中很难实现此操作。 任何帮助或建议表示赞赏。
我不确定这是否是你打算做的,但它在逻辑上看起来是错误的......
for(p=list; p!=NULL; p=p->next){
if(((strcmp(delete->last, p->last))!=0) || (strcmp(delete->first,p->first)!=0)
|| (strcmp(delete->email, p->email)!=0)){
printf("\nThis student does not exist.\n");
return list;
}
}
但是,除非第一个节点是您要删除的节点,否则这不会失败吗? 你开始一个循环,查看第一个节点,如果不匹配,你返回列表?
我认为其目的不是寻找否定,而是遍历节点,如果找到匹配项,则尽早结束循环 - 否则您想到达列表的末尾以检查所有节点。
for(p=list; p!=NULL; p=p->next){
if(((strcmp(delete->last, p->last))==0) && (strcmp(delete->first,p->first)==0)
|| (strcmp(delete->email, p->email)==0)){
printf("\nFound a match.\n");
// delete this node and end this for loop early, probably better to use a while loop here, while(strcmp()!=0 etc);
}
}
编辑 既然您已经使用 for 循环来查找记录,您可能想要进行另一次编辑。 您在第一个 for 循环中找到带有 strcmp(),=0 集合的记录,如果它找到了记录。 跳出循环,此时可以删除找到的记录!
这意味着您不需要再次重复循环来删除记录,并且如果它是列表中的第一条记录或后续记录,您将不会有两个不同的代码块。
//to check if student is in the list
for(p=list; p!=NULL; p=p->next){
if(((strcmp(delete->last, p->last))!=0) || (strcmp(delete->first,p->first)!=0)
|| (strcmp(delete->email, p->email)!=0)){
continue;
}
else {
// we found a match! Delete it
delete=p;
p->next = p->next->next;
free(delete);
printf("Student has been removed from the list.\n");
return list;
}
printf("\nThis student does not exist.\n");
return list;
}
// should never get here any more
} // end func.
如果你真的想保持你的代码原样,因为它对除第一条记录之外的所有记录都有效,那么你需要删除第一条记录才能工作。 == NULL 的检查看起来不对,因为如果没有其他链接到它,您只删除第一条记录? 我觉得这种逻辑是错误的。
// if we get here, we can assume that the first element matched,
// because otherwise we should never have gotten here
cur=list; //to remove first element
if(cur->next != NULL){ // if there is a next element
// set next to be the first
cur=cur->next;
}
free(delete);
printf("\nStudent has been removed from the list.\n");
return list;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.