创建嵌套结构的新列表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建嵌套结构的新列表相关的知识,希望对你有一定的参考价值。
我在尝试从旧的结构创建新的链接列表时遇到了一些麻烦。新链表的基础是,属于用户指定的特定品种的狗将被添加到新列表中,旧列表中的所有狗将不会被转移。将一只狗放入列表中我没有问题,但是当我尝试添加多只狗时,我认为我的代码出了问题。我假设当我创建指向列表结果的第二个临时列表时,当我添加到它时它会修改结果,但似乎并非如此。任何方向将不胜感激。
代码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 Center
");
do
{
printf("Please enter your selection:
");
printf(" a: add a new dog to the list
");
printf(" s: search for a dog on the list
");
printf(" c: add a checkup date for dog
");
printf(" b: display list of dogs of breed
");
printf(" q: quit
");
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 != '
' && 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!
");
}
}
void helper(char c)
{
if (c == 'a')
{
char input[100];
printf("
Please enter the dog's info in the following format:
");
printf("name:breed
");
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("
Dog added to list successfully
");
}
else
printf("
That dog is already on the list
");
}
else if (c == 's' || c == 'r' || c == 'c' || c == 'l')
{
char name[30];
printf("
Please enter the dog's name:
");
fgets(name, sizeof(name), stdin);
name[strlen(name) - 1] = ' ';
struct dog* result = search_dog(name);
if (result == NULL)
printf("
That dog is not on the list
");
else if (c == 's')
printf("
Breed: %s
", result->breed);
else if (c == 'c')
{
char date[30];
printf("
Please enter the date of the checkup:
");
fgets(date, sizeof(date), stdin);
date[strlen(date) - 1] = ' ';
add_checkup(name, date);
printf("
Checkup added
");
}
}
else if (c == 'b')
{
char breed[30];
printf("
Please enter the breed:
");
fgets(breed, sizeof(breed), stdin);
breed[strlen(breed) - 1] = ' ';
struct container* result = list_of_breed(breed);
printf("
List of dogs with breed type %s:
", 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("
There are no dogs on this list!
");
return;
}
while (container_traverser != NULL)
{
printf("Name: %s
", container_traverser->dog->name);
printf("Breed: %s
", 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("
%s", ptr->date);
ptr = ptr->next;
}
}
printf("
");
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
,你没有初始化成员checkupsof the newly malloc'ed
struct dog`。加
tempDog->checkups = NULL;
之后
strcpy(tempDog->breed, breed);
第二个
在list_of_breed
,你没有在使用之前设置next
的cont_dog
成员。
添加行
cont_add->next = NULL;
后
cont_add->dog = dog_add;
未来的问题
在list_of_breed
,你有这条线:
dog_add->checkups = temp->dog->checkups;
这使得checkups
的浅拷贝。为了避免free
ing checkups
不止一次,你需要制作checkups
的深层副本。
以上是关于创建嵌套结构的新列表的主要内容,如果未能解决你的问题,请参考以下文章