C语言双向链表通讯录,支持保存数据到文件加载数据到文件
时间: 2023-12-02 16:06:03 浏览: 110
C语言双向链表
5星 · 资源好评率100%
下面是一个简单的C语言双向链表实现通讯录,支持保存数据到文件和加载数据到文件的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义通讯录结构体
typedef struct _address_book {
char name[20]; // 姓名
char phone[20]; // 电话号码
struct _address_book *prev; // 上一个节点的指针
struct _address_book *next; // 下一个节点的指针
} address_book;
// 创建一个新的通讯录节点
address_book *new_address_book(char *name, char *phone) {
// 分配内存
address_book *node = (address_book *)malloc(sizeof(address_book));
if (node == NULL) {
printf("Error: memory allocation failed!\n");
exit(1);
}
// 复制数据
strncpy(node->name, name, 19);
strncpy(node->phone, phone, 19);
node->prev = NULL;
node->next = NULL;
return node;
}
// 添加一个通讯录节点到双向链表
void add_address_book(address_book **head, address_book *node) {
if (*head == NULL) { // 如果链表为空则直接添加
*head = node;
} else { // 否则添加到链表末尾
address_book *current = *head;
while (current->next != NULL) {
current = current->next;
}
current->next = node;
node->prev = current;
}
}
// 从双向链表中删除一个通讯录节点
void delete_address_book(address_book **head, char *name) {
if (*head == NULL) { // 如果链表为空则直接返回
return;
}
address_book *current = *head;
while (current != NULL) {
if (strcmp(current->name, name) == 0) { // 找到了要删除的节点
if (current == *head) { // 要删除的节点是头节点
*head = current->next;
if (*head != NULL) {
(*head)->prev = NULL;
}
} else { // 要删除的节点不是头节点
current->prev->next = current->next;
if (current->next != NULL) {
current->next->prev = current->prev;
}
}
free(current); // 释放内存
return;
}
current = current->next;
}
}
// 打印所有的通讯录节点
void print_address_book(address_book *head) {
printf("Name\tPhone\n");
printf("----\t-----\n");
address_book *current = head;
while (current != NULL) {
printf("%s\t%s\n", current->name, current->phone);
current = current->next;
}
printf("\n");
}
// 保存通讯录到文件
void save_address_book(address_book *head, char *filename) {
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
printf("Error: cannot open file %s for writing!\n", filename);
exit(1);
}
address_book *current = head;
while (current != NULL) {
fprintf(fp, "%s,%s\n", current->name, current->phone);
current = current->next;
}
fclose(fp);
}
// 从文件中加载通讯录
address_book *load_address_book(char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("Error: cannot open file %s for reading!\n", filename);
exit(1);
}
address_book *head = NULL;
char line[50];
char *name, *phone;
while (fgets(line, 50, fp) != NULL) {
// 解析行数据
name = strtok(line, ",");
phone = strtok(NULL, ",");
if (name != NULL && phone != NULL) {
// 创建新节点并添加到链表中
address_book *node = new_address_book(name, phone);
add_address_book(&head, node);
}
}
fclose(fp);
return head;
}
int main() {
address_book *head = NULL;
// 添加几个测试节点
add_address_book(&head, new_address_book("Alice", "123456"));
add_address_book(&head, new_address_book("Bob", "234567"));
add_address_book(&head, new_address_book("Charlie", "345678"));
// 打印通讯录
print_address_book(head);
// 保存通讯录到文件并从文件中加载
save_address_book(head, "address_book.txt");
address_book *new_head = load_address_book("address_book.txt");
// 打印新的通讯录
print_address_book(new_head);
// 删除一个节点并打印新的通讯录
delete_address_book(&new_head, "Bob");
print_address_book(new_head);
// 释放内存
address_book *current = new_head;
while (current != NULL) {
address_book *next = current->next;
free(current);
current = next;
}
return 0;
}
```
上面的代码演示了如何使用双向链表实现一个简单的通讯录,并支持保存数据到文件以及从文件中加载数据。可以根据实际需求进行修改和扩展。
阅读全文