Implementing a Dynamic Address Book with Singly Linked Lists in C
LinkedList Header Definition
The underlying data structure is a singly linked list. We define the node structure to hold generic data, which will be specialized for the contact information later.
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
#include <stdlib.h>
#include <assert.h>
#include "AddressBook.h"
typedef ContactData Item;
typedef struct Node {
Item data;
struct Node* next;
} Node;
// Fundamental list operations
void list_push_back(Node** head_ref, Item value);
void list_push_front(Node** head_ref, Item value);
void list_pop_back(Node** head_ref);
void list_pop_front(Node** head_ref);
void list_insert_after(Node* pos, Item value);
void list_erase(Node** head_ref, Node* pos);
void list_destroy(Node** head_ref);
#endif
Address Book Interface
This header defines the specific data structure for a contact and exposes the high-level API for managing the address book.
#ifndef ADDRESS_BOOK_H
#define ADDRESS_BOOK_H
#define MAX_NAME_LEN 32
#define MAX_PHONE_LEN 16
typedef struct ContactData {
char name[MAX_NAME_LEN];
char phone[MAX_PHONE_LEN];
} ContactData;
// The list itself is represented by a pointer to the head node
typedef Node* AddressBook;
void create_book(AddressBook* book);
void add_entry(AddressBook* book);
void remove_entry(AddressBook* book);
void display_book(AddressBook book);
void update_entry(AddressBook* book);
void delete_book(AddressBook* book);
#endif
Implementation Logic
The following source file implements the logic required to manipulate the linked list as an address book. It handles user input, memory management, and traversal logic.
#include "AddressBook.h"
#include "LinkedList.h"
#include <stdio.h>
#include <string.h>
void create_book(AddressBook* book) {
*book = NULL;
}
void add_entry(AddressBook* book) {
ContactData new_entry;
printf("Input Name: ");
scanf("%31s", new_entry.name);
printf("Input Phone Number: ");
scanf("%15s", new_entry.phone);
list_push_back(book, new_entry);
}
void remove_entry(AddressBook* book) {
char target[MAX_NAME_LEN];
printf("Enter name of contact to delete: ");
scanf("%31s", target);
Node* current = *book;
Node* previous = NULL;
// Traverse the list to find the node
while (current != NULL) {
if (strcmp(current->data.name, target) == 0) {
if (previous == NULL) {
// Removing the head node
*book = current->next;
} else {
previous->next = current->next;
}
free(current);
printf("Contact removed successfully.\n");
return;
}
previous = current;
current = current->next;
}
printf("Error: Contact not found.\n");
}
void display_book(AddressBook book) {
Node* iterator = book;
if (!iterator) {
printf("The address book is empty.\n");
return;
}
printf("%-20s %-15s\n", "Name", "Phone");
printf("-------------------------------\n");
while (iterator != NULL) {
printf("%-20s %-15s\n", iterator->data.name, iterator->data.phone);
iterator = iterator->next;
}
}
void update_entry(AddressBook* book) {
char target[MAX_NAME_LEN];
printf("Enter name of contact to modify: ");
scanf("%31s", target);
Node* iterator = *book;
while (iterator != NULL) {
if (strcmp(iterator->data.name, target) == 0) {
printf("Enter new Name: ");
scanf("%31s", iterator->data.name);
printf("Enter new Phone: ");
scanf("%15s", iterator->data.phone);
printf("Contact updated.\n");
return;
}
iterator = iterator->next;
}
printf("Error: Contact not found.\n");
}
void delete_book(AddressBook* book) {
list_destroy(book);
}