2016-10-11 3 views
3

У меня возникли проблемы с созданием нового связанного списка структур из старого. Основой нового связанного списка является то, что собаки, относящиеся к определенной породе, указанные пользователем, будут добавлены в новый список, а все из старого списка не будут перенесены. У меня нет проблем с получением одной собаки в списке, но я думаю, что что-то не так с моим кодом, когда я пытаюсь добавить несколько собак. Я предположил, что, когда я создал второй список тем, который указывает на результаты списка, при добавлении к нему он изменит результаты, но это, похоже, не так. Любое направление будет оценено по достоинству.Создание нового списка вложенных структур

Последняя функция в коде 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\n\n"); 

    do 
    { 
     printf("Please enter your selection:\n"); 
     printf("\ta: add a new dog to the list\n"); 
     printf("\ts: search for a dog on the list\n"); 
     printf("\tc: add a checkup date for dog\n"); 
     printf("\tb: display list of dogs of breed\n"); 
     printf("\tq: quit\n"); 
     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:breed\n"); 
     fgets(input, sizeof(input), stdin); 


     input[strlen(input) - 1] = '\0'; 

     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 successfully\n\n"); 
     } 
     else 
      printf("\nThat dog is already on the list\n\n"); 
    } 
    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] = '\0'; 

     struct dog* result = search_dog(name); 

     if (result == NULL) 
      printf("\nThat dog is not on the list\n\n"); 
     else if (c == 's') 
      printf("\nBreed: %s\n\n", 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] = '\0'; 

      add_checkup(name, date); 
      printf("\nCheckup added\n\n"); 
     } 

    } 
    else if (c == 'b') 
    { 
     char breed[30]; 

     printf("\nPlease enter the breed:\n"); 
     fgets(breed, sizeof(breed), stdin); 

     breed[strlen(breed) - 1] = '\0'; 

     struct container* result = list_of_breed(breed); 

     printf("\nList of dogs with breed type %s:\n\n", 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!\n\n"); 
     return; 
    } 

    while (container_traverser != NULL) 
    { 
     printf("Name: %s\n", container_traverser->dog->name); 
     printf("Breed: %s\n", 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("\n\n"); 
     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; 
} 
+1

Что такое? Просьба представить полный образец кода. http://stackoverflow.com/help/mcve – Peanut

+0

список сделан из контейнера, но я настроил его в другой функции. Я пытаюсь взять узлы из этого списка и добавить его в этот новый список. – poomulus

+1

Вы прочитали эту ссылку? Попробуйте дать пример кода, который воспроизводит проблему, которую вы имеете, и что люди могут запускать, тогда они с большей вероятностью помогут вам и смогут лучше. – Peanut

ответ

0

Я заметил следующие проблемы. У вас есть пара неинициализированных членов, и вы их используете. Как следствие, ваша программа имеет неопределенное поведение.

Первый Один

В add_doc, вы не инициализируются проверок членов of the newly malloc'ed структура 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.

Смежные вопросы