获取附加到链表的输入,而不再次获取相同的输入-C
我试图从用户那里获取输入,然后将结构附加到链表的末尾。这很好,但是我想添加另一个特性,如果所有细节都完全相同,那么它将阻止添加输入。(在本例中为电子邮件、班级、名字和姓氏)获取附加到链表的输入,而不再次获取相同的输入-C,c,linked-list,C,Linked List,我试图从用户那里获取输入,然后将结构附加到链表的末尾。这很好,但是我想添加另一个特性,如果所有细节都完全相同,那么它将阻止添加输入。(在本例中为电子邮件、班级、名字和姓氏) 我在中间添加的for循环是为了达到这个特性所做的。程序进入循环没有任何问题,但仍将添加输入。我该如何解决这个问题 struct request *append(struct request *list){ char f_name[NAME_LEN+1]; char l_name[NAME_LEN+1];
我在中间添加的for循环是为了达到这个特性所做的。程序进入循环没有任何问题,但仍将添加输入。我该如何解决这个问题
struct request *append(struct request *list){
char f_name[NAME_LEN+1];
char l_name[NAME_LEN+1];
char e_address[EMAIL_LEN+1];
char c_name[CLASS_LEN+1];
//get input
printf("\nEnter email: ");
scanf("%s", e_address);
printf("\nEnter class: ");
scanf("%s", c_name);
printf("\nEnter child first name: ");
scanf("%s", f_name);
printf("\nEnter child last name: ");
scanf("%s", l_name);
//allocate memory for the structure
struct request* p = (struct request*) malloc(sizeof(struct request));
struct request *temp = list;
//////////WHAT I TRIED BUT DIDN'T WORK
for (p = list, temp = NULL; p != NULL; temp = p, p = p -> next) {
if (strcmp(p -> first, f_name) == 0 && strcmp(p -> last, l_name) == 0 && strcmp(p -> email, e_address) == 0 && strcmp(p -> class, c_name) == 0) {
printf("Output: request already exists");
return list;
}
}
//store the data
strcpy(p->first, f_name);
strcpy(p->last, l_name);
strcpy(p->email, e_address);
strcpy(p->class, c_name);
p->next = NULL;
//if list is empty return pointer to the newly created linked list
if (list == NULL) {
return p;
}
//traverse to the end of the list and append the new list to the original list
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = p;
return list;
}
首先,对于那些scanf,您应该做一些类似于避免缓冲区溢出的事情 至于您的问题,您应该在for循环之后malloc
p
,因为我们应该只在没有其他节点具有完全相同的信息时分配它(正如paddy所说,在您的代码中,它会导致内存泄漏,因为您将p
设置为指向其他节点,从而丢失新malloc-ed数据)
您的循环比需要的更复杂。诚然,我不明白为什么for循环不会检测到副本,也许提供一些输入案例可以帮助清理它?无论哪种方式,我都会将代码的这一部分替换为:
// Get a pointer to the head of the list
struct request *temp = list;
// Find and node with the exact same data
while(temp->next != NULL) {
if(!strcmp(temp->first, f_name) && !strcmp(temp->last, l_name) && !strcmp(temp->email, e_address) && !strcmp(temp->class, c_name)){
printf("Output: request already exists");
return list;
}
temp = temp->next;
}
// Allocate p and reset temp
struct request *p = (struct request*) malloc(sizeof(struct request));
temp = list;
// etc
循环会立即泄漏刚才分配的内存,因为它会重新分配存储在
p
中的值。关于风格的一个重要注意事项。。。不要在结构间接寻址之间放置空格:使用p->first
而不是p->first
。这将使您的代码更具可读性。只有完全的初学者才会在那里放空格,通常在他们停止之前,必须有人告诉他们“第一个”是未初始化的?您正在混合“接口”和“实现”,不要这样做。您的“界面”是提示用户并接收和验证所有用户输入的用户界面。你的“实现”是你的数据处理,你的链表。把两者分开。创建一个函数,用于处理与用户的接口并填充结构请求
。然后您的实现将是一个add()
或push()
函数,它将struct请求添加为列表中的节点。将接口和实现分开将允许您在这两方面做得更好,并使代码更易于维护。