Menu
Coddy logo textTech

Putting It All Together

Part of the Logic & Flow section of Coddy's C journey — lesson 54 of 63.

challenge icon

Challenge

Easy

Complete your contact management system by integrating all the functions you've created in the previous lessons. Your program should:

  1. Use the same Contact struct definition from the previous lessons with members:
    • A character array name with size 50
    • A character array phone with size 20
    • A character array email with size 40
    • An integer age
  2. Use the same createContact function from previous lessons that:
    • Dynamically allocates memory for a Contact struct
    • Initializes all members to default values
    • Returns a pointer to the contact
  3. Use the same populateContact function from previous lessons that:
    • Takes a pointer to a Contact struct as its parameter
    • Prompts for user input and populates all contact fields
    • Validates the input data
  4. Write a displayContact function that:
    • Takes a constant pointer to a Contact struct as its parameter
    • Prints each field on its own line in this exact format:
      Name: John
      Phone: 555-1234
      Email: john@email.com
      Age: 25
  5. Write a function named updateContact that:
    • Takes a pointer to a Contact struct as its parameter
    • Returns nothing (void)
    • Prompts the user to choose which field to update by printing:
      • What would you like to update?
      • 1. Name
      • 2. Phone
      • 3. Email
      • 4. Age
      • Enter choice (1-4):
    • Reads the user's choice and updates the corresponding field:
      • If choice is 1: prints Enter new name: and updates the name
      • If choice is 2: prints Enter new phone: and updates the phone
      • If choice is 3: prints Enter new email: and updates the email
      • If choice is 4: prints Enter new age: and updates the age
      • If choice is invalid (not 1-4): prints Invalid choice
    • After a successful update, prints Contact updated successfully
  6. In the main function, implement a complete contact management workflow:
    • Create a contact using the createContact function
    • Check if contact creation was successful
    • Call the populateContact function to fill in the initial contact data
    • Print --- Initial Contact ---
    • Call the displayContact function to show the initial contact information
    • Print --- Updating Contact ---
    • Call the updateContact function to modify one field
    • Print --- Updated Contact ---
    • Call the displayContact function again to show the updated contact information
    • Free the dynamically allocated memory
    • Print Contact management completed

Note: The displayContact function in this lesson uses a simple format — one line per field with no extra details or units (e.g., age is printed as a plain number, not "25 years old"). Make sure your output matches the format shown above exactly, as the test cases depend on it.

This final challenge brings together all the components of your contact management system: struct definition, dynamic memory allocation, data input and validation, formatted display, and data modification. You'll demonstrate the complete lifecycle of a dynamically allocated struct from creation to cleanup, while practicing function organization and the proper use of pointers throughout the entire process.

Try it yourself

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Contact {
    char name[50];
    char phone[20];
    char email[40];
    int age;
};

struct Contact* createContact() {
    struct Contact* contact = (struct Contact*)malloc(sizeof(struct Contact));
    if (contact != NULL) {
        strcpy(contact->name, "");
        strcpy(contact->phone, "");
        strcpy(contact->email, "");
        contact->age = 0;
    }
    return contact;
}

void populateContact(struct Contact* contactPtr) {
    printf("Enter name: ");
    fgets(contactPtr->name, sizeof(contactPtr->name), stdin);
    contactPtr->name[strcspn(contactPtr->name, "\n")] = '\0';
    
    printf("Enter phone: ");
    fgets(contactPtr->phone, sizeof(contactPtr->phone), stdin);
    contactPtr->phone[strcspn(contactPtr->phone, "\n")] = '\0';
    
    printf("Enter email: ");
    fgets(contactPtr->email, sizeof(contactPtr->email), stdin);
    contactPtr->email[strcspn(contactPtr->email, "\n")] = '\0';
    
    printf("Enter age: ");
    scanf("%d", &contactPtr->age);
}

void displayContact(const struct Contact *contactPtr) {
    printf("=== CONTACT DETAILS ===\n");
    printf("Name: %s\n", contactPtr->name);
    printf("Phone: %s\n", contactPtr->phone);
    printf("Email: %s\n", contactPtr->email);
    printf("Age: %d years old\n", contactPtr->age);
    printf("========================\n");
    
    printf("Name length: %lu characters\n", strlen(contactPtr->name));
    
    if (contactPtr->age >= 0 && contactPtr->age <= 12) {
        printf("Generation: Child\n");
    } else if (contactPtr->age >= 13 && contactPtr->age <= 19) {
        printf("Generation: Teenager\n");
    } else if (contactPtr->age >= 20 && contactPtr->age <= 39) {
        printf("Generation: Young Adult\n");
    } else if (contactPtr->age >= 40 && contactPtr->age <= 59) {
        printf("Generation: Middle-aged Adult\n");
    } else if (contactPtr->age >= 60) {
        printf("Generation: Senior\n");
    }
    
    if (strchr(contactPtr->email, '@') != NULL) {
        printf("Email format: Valid\n");
    } else {
        printf("Email format: Invalid\n");
    }
}

int main() {
    struct Contact* contact = createContact();
    
    if (contact != NULL) {
        populateContact(contact);
        displayContact(contact);
        free(contact);
        printf("Program completed successfully\n");
    }
    
    return 0;
}

All lessons in Logic & Flow