用链表来实现通讯录并保存到文件中

前言

上次介绍了链表,那么这次我们用链表来实现通讯录,其中用到了链表、循环、数据结构、指针、还有malloc内存函数、fread和fwrite文件操作函数。
我们在实现通讯录中要具备几项功能:
1.创建链表
2.输出链表内容
3.删除链表中的内容
4.修改链表中的内容
5.添加新内容在链表
6.把链表的内容读入文件并保存
7.从文件中读入内容放进链表
最后来看完整的代码加代码效果吧。

一、先建一个通讯录的框架

我们可以利用switch循环体来做一个功能选择的模式,其中用到了枚举的可读性方便来选择功能。
代码如下:
在这里插入图片描述
这是枚举
在这里插入图片描述

二、功能的实现

1.先创建链表

我们是创建通讯录,通讯录中有,姓名、性别、年龄、电话号码、地址。
我们先创建一个节点结构体:
在这里插入图片描述
链表结构示意图:
在这里插入图片描述
这head表示头指针,这个指针变量保存一个头节点地址。
节点中pNext指针是指向下一个节点来连接这些节点,由此就叫他们为链表。
最后一个节点中pNext指向NULL。
代码如下:
在这里插入图片描述

2.输出链表内容

通过头指针指向的头节点一一向后查看,这里就用到了每个节点中的pNext指针。
代码如下:
在这里插入图片描述

3.删除链表中的内容

删除就是释放,就是把我们想删除的节点释放,然后把这个节点的前后节点连接就行。
我们先用输出链表内容的函数来查看我们想删除哪个。
代码如下:
在这里插入图片描述

4.修改链表中的内容

我们先调用输出链表内容函数来查看想修改的节点,再用switch来选择要修改的内容。
代码如下:
在这里插入图片描述

5.添加新内容在链表中

我们可以把我们想添加的新成员在头节点进行,就是抢头节点的称号,自己当头节点。
代码如下:
在这里插入图片描述

6.把链表的内容读入文件并保存

这里利用fread函数来实现,也用for循环来一个一个读入文件中。
这里需要一个函数来计算节点的个数。
计数代码如下:
在这里插入图片描述
保存文件的代码如下:
在这里插入图片描述

7.从文件中读入内容放进链表

这样可以把我们上次的内容重新在链表中呈现。
这里我们又要一个一个开辟空间来创建节点。
代码如下:
在这里插入图片描述

三.完整的代码加效果

这是头文件的代码:
在这里插入图片描述
这是main函数的代码:
在这里插入图片描述
这是功能函数实现的代码:
这个代码太长我分成了两个图。
在这里插入图片描述

在这里插入图片描述

效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

写到这里就完了,有写不到位的地方欢迎留言。

  • 31
    点赞
  • 150
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
下面是一个简单的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; } ``` 上面的代码演示了如何使用双向链表实现一个简单的通讯录,并支持保存数据文件以及从文件加载数据。可以根据实际需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世_生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值