Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获取附加到链表的输入,而不再次获取相同的输入-C_C_Linked List - Fatal编程技术网

获取附加到链表的输入,而不再次获取相同的输入-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请求添加为列表中的节点。将接口和实现分开将允许您在这两方面做得更好,并使代码更易于维护。