Thread: Family tree

  1. #1
    Registered User
    Join Date
    Nov 2022
    Posts
    8

    Post Family tree

    So I've built a simple code that basically function as a family tree, but there's always an issue when it comes to marrying two people or printing the cousins. PLEASE HELP

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_NAME_LENGTH 50
    
    typedef struct Person {
      char name[MAX_NAME_LENGTH];
      int age;
      struct Person *spouse;
      struct Person *child;
    } Person;
    
    // Function prototypes
    void addHead(Person ** family);
    void marry(Person ** family);
    void addOffspring(Person ** family);
    void printFamily(Person ** family);
    void yearsPass(Person ** family);
    void countPeople(Person ** family);
    void printCousins(Person ** family);
    
    void printCousinsRecursive(Person * person, int targetDegree,
                               int currentDegree);
    void printSiblings(Person * sibling, int targetDegree, int currentDegree);
    void freeFamily(Person ** family);
    
    int main()
    {
      int choice;
      Person *family = NULL;
    
      do {
        printf("Choose an option:\n");
        printf("0. Exit\n");
        printf("1. Add a head\n");
        printf("2. Marry two people\n");
        printf("3. Add an offspring\n");
        printf("4. Print family top-down\n");
        printf("5. Years pass\n");
        printf("6. Count people\n");
        printf("7. Print cousins\n");
        scanf("%d", &choice);
    
        switch (choice) {
        case 0:
          break;
        case 1:
          addHead(&family);
          break;
        case 2:
          marry(&family);
          break;
        case 3:
          addOffspring(&family);
          break;
        case 4:
          printFamily(&family);
          break;
        case 5:
          yearsPass(&family);
          break;
        case 6:
          countPeople(&family);
          break;
        case 7:
          printf("Cousins:\n");
          printCousins(&family);
          printf("\n");
          break;
        default:
          printf("Invalid option\n");
          break;
        }
    
      } while (choice != 0);
    
      freeFamily(&family);
    
      return 0;
    }
    
    void freeFamily(Person ** family)
    {
      Person *current = *family;
      while (current != NULL) {
        Person *nextPerson = current->child;
    
        // Free the current person
        free(current);
    
        // Move to the next person
        current = nextPerson;
      }
    
      // Set the family pointer to NULL
      *family = NULL;
    }
    
    void addHead(Person ** family)
    {
      char name[MAX_NAME_LENGTH];
      int age;
    
      getchar();
      printf("Enter a name:\n");
      fgets(name, sizeof(name), stdin);
      name[strcspn(name, "\n")] = '\0';
    
      // Check if the name is already taken
      if (*family != NULL && strcmp((*family)->name, name) == 0) {
        printf("The name is already taken\n");
        return;
      }
    
      printf("Enter age:\n");
      scanf("%d", &age);
    
      // Create a new person
      Person *head = (Person *) malloc(sizeof(Person));
      strcpy(head->name, name);
      head->age = age;              // Store the entered age
      head->spouse = NULL;
      head->child = NULL;
    
      // Set the new person as the family head
      *family = head;
    }
    
    void marry(Person ** family)
    {
      getchar();
      char name1[MAX_NAME_LENGTH], name2[MAX_NAME_LENGTH];
      printf("Enter the name of the first person:\n");
      fgets(name1, sizeof(name1), stdin);
      name1[strcspn(name1, "\n")] = '\0';
      printf("Enter the name of the second person:\n");
      fgets(name2, sizeof(name2), stdin);
      name2[strcspn(name2, "\n")] = '\0';
    
      // Find the first person
      Person *person1 = *family;
      while (person1 != NULL && strcmp(person1->name, name1) != 0)
        person1 = person1->child;
    
      // Find the second person
      Person *person2 = *family;
      while (person2 != NULL && strcmp(person2->name, name2) != 0)
        person2 = person2->child;
    
      // Check if both persons were found
      if (person1 == NULL || person2 == NULL) {
        printf("One of the persons does not exist\n");
        return;
      }
      // Check if one of them is already married
      if (person1->spouse != NULL || person2->spouse != NULL) {
        printf("Invalid marriage\n");
        return;
      }
      // Check if they have a common previous head (same family)
      Person *commonHead = *family;
      while (commonHead != NULL
             && (commonHead->child == NULL
                 || (commonHead->child != person1 && commonHead->child != person2)))
        commonHead = commonHead->child;
    
      if (commonHead != NULL) {
        printf("Invalid marriage\n");
        return;
      }
      // Check if one of them is under the age of 18
      if (person1->age < 18 || person2->age < 18) {
        printf("Invalid marriage\n");
        return;
      }
      // Update the spouse pointers
      person1->spouse = person2;
      person2->spouse = person1;
    
      printf("%s and %s are now married\n", person1->name, person2->name);
    }
    
    void addOffspring(Person ** family)
    {
      getchar();
      char parent1[MAX_NAME_LENGTH], parent2[MAX_NAME_LENGTH],
          offspring[MAX_NAME_LENGTH];
      printf("Enter the name of the first parent:\n");
      fgets(parent1, sizeof(parent1), stdin);
      parent1[strcspn(parent1, "\n")] = '\0';
    
      printf("Enter the name of the second parent:\n");
      fgets(parent2, sizeof(parent2), stdin);
      parent2[strcspn(parent2, "\n")] = '\0';
    
      printf("Enter offspring's name:\n");
      fgets(offspring, sizeof(offspring), stdin);
      offspring[strcspn(offspring, "\n")] = '\0';
    
      // Find the first parent
      Person *person1 = *family;
      while (person1 != NULL && strcmp(person1->name, parent1) != 0)
        person1 = person1->child;
    
      // Find the second parent
      Person *person2 = *family;
      while (person2 != NULL && strcmp(person2->name, parent2) != 0)
        person2 = person2->child;
    
      // Check if both parents were found
      if (person1 == NULL || person2 == NULL) {
        printf("One of the parents does not exist\n");
        return;
      }
      // Check if the parents are married
      if (person1->spouse != person2 || person2->spouse != person1) {
        printf("The parents are not married\n");
        return;
      }
      // Check if the offspring's name is already taken
      Person *existingPerson = *family;
      while (existingPerson != NULL) {
        if (strcmp(existingPerson->name, offspring) == 0) {
          printf("The name is already taken\n");
          return;
        }
        existingPerson = existingPerson->child;
      }
    
      // Create a new offspring
      Person *newOffspring = (Person *) malloc(sizeof(Person));
      strcpy(newOffspring->name, offspring);
      newOffspring->spouse = NULL;
      newOffspring->child = NULL;
    
      // Set the new offspring's parents
      newOffspring->child = person1->child;
      person1->child = newOffspring;
    
      printf("%s was born\n", newOffspring->name);
    }
    
    void printFamily(Person ** family)
    {
      char name[MAX_NAME_LENGTH];
      printf("Enter the name of the person:\n");
      fgets(name, sizeof(name), stdin);
      name[strcspn(name, "\n")] = '\0';
    
      // Find the person
      Person *person = *family;
      while (person != NULL && strcmp(person->name, name) != 0)
        person = person->child;
    
      // Check if the person was found
      if (person == NULL) {
        printf("Person not found\n");
        return;
      }
      // Print the person and their family
      printf("%s (%d)", person->name, person->age);
    
      if (person->spouse != NULL) {
        printf(" - %s (%d)\n", person->spouse->name, person->spouse->age);
    
        Person *child = person->child;
        while (child != NULL) {
          printf("\t%s (%d)\n", child->name, child->age);
          child = child->child;
        }
      } else {
        printf("\n");
      }
    }
    
    void yearsPass(Person ** family)
    {
      int years;
      printf("Enter number of years:\n");
      scanf("%d", &years);
    
      // Traverse the family tree and add years to each person's age
      Person *current = *family;
      while (current != NULL) {
        current->age += years;
        current = current->child;
      }
    
    }
    
    void countPeople(Person ** family)
    {
      int count = 0;
    
      // Traverse the family tree and count the number of people
      Person *current = *family;
      while (current != NULL) {
        count++;
        current = current->child;
      }
    
      // Print the count of people
      if (count == 1) {
        printf("There is one person\n");
      } else {
        printf("There are %d people\n", count);
      }
    }
    
    void printCousins(Person ** family)
    {
      char name[MAX_NAME_LENGTH];
      int degree;
    
      printf("Enter the name of the person:\n");
      scanf("%s", name);
      printf("Enter degree:\n");
      scanf("%d", &degree);
    
      // Find the person
      Person *person = *family;
      while (person != NULL && strcmp(person->name, name) != 0)
        person = person->child;
    
      // Check if the person was found
      if (person == NULL) {
        printf("Person not found\n");
        return;
      }
      // Print the person
      printf("%s\n", person->name);
    
      // Print cousins of the specified degree
      printCousinsRecursive(person, degree, 1);
    }
    
    void printCousinsRecursive(Person * person, int targetDegree, int currentDegree)
    {
      if (currentDegree > targetDegree)
        return;
    
      Person *current = person;
      while (current != NULL) {
        if (current->spouse != NULL) {
          printSiblings(current->spouse->child, targetDegree, currentDegree);
        }
        current = current->child;
      }
    }
    
    void printSiblings(Person * sibling, int targetDegree, int currentDegree)
    {
      while (sibling != NULL) {
        if (currentDegree <= targetDegree) {
          printf("%s\n", sibling->name);
          printCousinsRecursive(sibling, targetDegree, currentDegree + 1);
        }
        sibling = sibling->child;
      }
    }
    Last edited by Salem; 06-21-2023 at 12:40 PM. Reason: removed crayoia

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    So what's the minimum number of things you type in for it to all go wrong.

    Sure, we could stare at the code for an hour or two (not likely), or we could just run the code (using a debugger) and a known test case which breaks it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Family Tree
    By Farnaz in forum C++ Programming
    Replies: 0
    Last Post: 03-07-2011, 12:50 PM
  2. Rooted Tree (Family tree)
    By ch4 in forum C Programming
    Replies: 4
    Last Post: 10-14-2008, 04:24 PM
  3. Family Holiday
    By KONI in forum Contests Board
    Replies: 3
    Last Post: 05-12-2007, 06:25 AM
  4. php owns your family
    By Aran in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 05-19-2002, 06:45 PM
  5. family tree
    By laloski in forum C++ Programming
    Replies: 2
    Last Post: 02-20-2002, 01:51 AM

Tags for this Thread