C语言 创建新的嵌套结构列表



我有一点麻烦,试图从一个旧的结构创建一个新的链表。新链表的基础是将属于用户指定的特定品种的狗添加到新链表中,旧链表中的所有狗都不会结转。我没有问题得到一只狗进入列表,但我认为我的代码是错误的,当我试图添加多个狗。我假设当我创建指向列表结果的第二个临时列表时,当我添加到它时,它会修改结果,但情况似乎并非如此。任何指示将不胜感激。

代码struct container* list_of_breed(char* breed)中的最后一个函数是我似乎有问题的函数。其他一切都按预期进行。我相信else语句是我似乎出错的地方,因为当只有一只狗与该品种匹配时,它似乎能够从它们中列出列表。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#pragma warning(disable: 4996)
// used to create a linked list of containers, each contaning a "dog"
struct container {
    struct dog *dog;
    struct container *next;
} *list = NULL;
// used to hold dog information and linked list of "checkups"
struct dog {
    char name[30];
    char breed[30];
    struct checkup *checkups;
};
// used to create a linked list of checkups containing "dates"
struct checkup {
    char date[30];
    struct checkup *next;
};
void flush();
void branching(char);
void helper(char);
void remove_all(struct container*);
void display(struct container*);
void                add_dog(char*, char*);              
struct dog*         search_dog(char*);                  
void                add_checkup(char*, char*);                                                  
struct container*   list_of_breed(char*);               
int main()
{
    char ch = 'i';
    printf("Dog Adoption Centernn");
    do
    {
        printf("Please enter your selection:n");
        printf("ta: add a new dog to the listn");
        printf("ts: search for a dog on the listn");
        printf("tc: add a checkup date for dogn");
        printf("tb: display list of dogs of breedn");
        printf("tq: quitn");
        ch = tolower(getchar());
        flush();
        branching(ch);
    } while (ch != 'q');
    remove_all(list);
    list = NULL;
    _CrtDumpMemoryLeaks();
    return 0;
}

void flush()
{
    int c;
    do c = getchar(); while (c != 'n' && c != EOF);
}

void branching(char c)
{
    switch (c)
    {
    case 'a':
    case 's':
    case 'r':
    case 'c':
    case 'l':
    case 'b':
    case 'n': helper(c); break;
    case 'q': break;
    default: printf("Invalid input!n");
    }
}

void helper(char c)
{
    if (c == 'a')
    {
        char input[100];
        printf("nPlease enter the dog's info in the following format:n");
        printf("name:breedn");
        fgets(input, sizeof(input), stdin);

        input[strlen(input) - 1] = '';
        char* name = strtok(input, ":"); 
        char* breed = strtok(NULL, ":");
        struct dog* result = search_dog(name);
        if (result == NULL)
        {
            add_dog(name, breed);
            printf("nDog added to list successfullynn");
        }
        else
            printf("nThat dog is already on the listnn");
    }
    else if (c == 's' || c == 'r' || c == 'c' || c == 'l')
    {
        char name[30];
        printf("nPlease enter the dog's name:n");
        fgets(name, sizeof(name), stdin);

        name[strlen(name) - 1] = '';
        struct dog* result = search_dog(name);
        if (result == NULL)
            printf("nThat dog is not on the listnn");
        else if (c == 's')
            printf("nBreed: %snn", result->breed);
        else if (c == 'c')
        {
            char date[30];
            printf("nPlease enter the date of the checkup:n");
            fgets(date, sizeof(date), stdin);

            date[strlen(date) - 1] = '';
            add_checkup(name, date);
            printf("nCheckup addednn");
        }
    }
    else if (c == 'b')
    {
        char breed[30];
        printf("nPlease enter the breed:n");
        fgets(breed, sizeof(breed), stdin);
        breed[strlen(breed) - 1] = '';
        struct container* result = list_of_breed(breed);
        printf("nList of dogs with breed type %s:nn", breed);
        display(result);
        remove_all(result);
        result = NULL;
    }
}

void remove_all(struct container* dogs)
{
    struct checkup* temp;
    if (dogs != NULL)
    {
        remove_all(dogs->next);
        while (dogs->dog->checkups != NULL)
        {
            temp = dogs->dog->checkups;
            dogs->dog->checkups = dogs->dog->checkups->next;
            free(temp);
        }
        free(dogs->dog);
        free(dogs);
    }
}

void display(struct container* dogs)
{
    struct container* container_traverser = dogs;
    if (container_traverser == NULL)
    {
        printf("nThere are no dogs on this list!nn");
        return;
    }
    while (container_traverser != NULL) 
    {
        printf("Name: %sn", container_traverser->dog->name);
        printf("Breed: %sn", container_traverser->dog->breed);
        printf("Checkups on file: ");
        struct checkup* ptr = container_traverser->dog->checkups;
        if (ptr == NULL)
        {
            printf("No checkups documented.");
        }
        else
        {
            while (ptr != NULL) 
            {
                printf("n%s", ptr->date);
                ptr = ptr->next;
            }
        }
        printf("nn"); 
        container_traverser = container_traverser->next;
    }
}
void add_dog(char* name, char* breed)
{
    struct dog *tempDog = (struct dog *) malloc(sizeof(struct dog));
    strcpy(tempDog->name, name);
    strcpy(tempDog->breed, breed);
    struct container *tempCont = (struct container *) malloc(sizeof(struct container));
    tempCont->dog = tempDog;
    tempCont->next = list;
    list = tempCont;

}
struct dog* search_dog(char* name)
{
    struct container *temp = list;

    while (temp != NULL) {
        if (strcmp(temp->dog->name, name) == 0) {
            return temp->dog;
        }
        temp = temp->next;
    }
    return NULL;
}
void add_checkup(char* name, char* date)
{
    struct container *tempList = (struct container *) malloc(sizeof(struct container));
    tempList = list;
    struct checkup *tempCheck = (struct checkup *) malloc(sizeof(struct checkup));
    while (tempList != NULL) {
        if (strcmp(tempList->dog->name, name) == 0) {
            strcpy(tempCheck->date, date);
            tempList->dog->checkups = tempCheck;
        }
        tempList = tempList->next;
    }
}

//THIS IS THE FUNCTION I AM HAVING ISSUES WITH SPECIFICALLY RETURNING MULTIPLE STRUCTURES TO THE LIST
struct container* list_of_breed(char* breed)
{
    struct container* result = NULL;
    struct container* temp = list;
    while (temp != NULL) {
        struct dog* tempDog = (struct dog*) malloc(sizeof(struct dog));
        tempDog = temp->dog;
        if (strcmp(temp->dog->breed, breed) == 0) {
            struct container *cont_add = (struct container*) malloc(sizeof(struct container));
            struct dog *dog_add = (struct dog*) malloc(sizeof(struct dog));
            strcpy(dog_add->name, temp->dog->name);
            strcpy(dog_add->breed, breed);
            dog_add->checkups = temp->dog->checkups;
            cont_add->dog = dog_add;
            if (result == NULL) {
                result = cont_add;
            }
            else {      
                struct container* temp2 = result;
                while (temp2->next != NULL) {
                    temp2 = temp2->next;
                }
                temp2->next = cont_add;
            }
        }
        temp = temp->next;
    }
    return result;
}

我注意到以下问题。你有几个未初始化的成员,你使用它们。因此,您的程序具有未定义的行为。

第一个

add_doc中,您没有初始化成员检查of the newly malloc'ed struct dog '。添加

tempDog->checkups = NULL;

行之后
strcpy(tempDog->breed, breed);

第二个

list_of_breed中,您在使用cont_dog之前没有设置next成员。

添加

     cont_add->next = NULL;

     cont_add->dog = dog_add;
未来问题

list_of_breed中,有一行:

     dog_add->checkups = temp->dog->checkups;

这是checkups的浅拷贝。为了避免free多次访问checkups,您需要对checkups进行深度复制。

相关内容

  • 没有找到相关文章

最新更新