当前位置: 首页 > news >正文

宁波网站设计方案做网站好公司有哪些

宁波网站设计方案,做网站好公司有哪些,集团高端网站建设,嘉兴网站制作费用#x1f493;博客主页#xff1a;江池俊的博客⏩收录专栏#xff1a;C语言进阶之路#x1f449;专栏推荐#xff1a;✅C语言初阶之路 ✅数据结构探索✅C语言刷题专栏#x1f4bb;代码仓库#xff1a;江池俊的代码仓库#x1f389;欢迎大家点赞#x1f44d;评论#x… 博客主页江池俊的博客⏩收录专栏C语言进阶之路专栏推荐✅C语言初阶之路 ✅数据结构探索✅C语言刷题专栏代码仓库江池俊的代码仓库欢迎大家点赞评论收藏⭐ 文章目录 前言 ♨️一、静态通讯录1.1 通讯录的前期准备1.1.1 创建菜单1.1.2 创建结构体1.1.3 头文件的包含和#define定义常量1.1.4 接口函数的声明1.1.5 实现通讯录菜单选项的对接 1.2 通讯录函数功能的实现1.2.1 初始化通讯录1.2.2 添加联系人1.2.3 删除联系人1.2.4 查找联系人1.2.5 修改联系人信息1.2.6 打印通讯录信息1.2.7 排序通讯录 1.3 静态通讯录源代码1.3.1 Contact.h 文件1.3.2 Contact.c 文件1.3.3 test.c 文件 ♨️二、通讯录优化之动态通讯录2.1 通讯录结构体的优化2.2 通讯录初始化函数的优化2.3 添加扩容函数2.4 释放动态开辟的内存2.5 动态通讯录源代码2.5.1 Contact.h 文件2.5.2 Contact.c 文件2.5.3 test.c 文件 ♨️三、通讯录优化之文件版通讯录3.1 保存通讯录信息到文件3.2 在初始化时加载文件信息到通讯录3.3 文件版通讯录源代码3.3.1 Contact.h 文件3.3.2 Contact.c 文件3.3.3 test.c 文件 前言 在现代社会中通讯录已经成为了我们生活中不可或缺的一部分。无论是工作还是生活我们都需要一个可靠的通讯录来记录和管理我们的联系人信息。 本文将介绍用C语言来实现一个通讯录管理系统其中主要存储了若干联系人的信息每个人的信息包括他们的姓名、年龄、性别、电话号码、住址等。并且该通讯录包括以下功能 增加联系人删除联系人查找联系人修改联系人打印通讯录排序通讯录退出程序 在写通讯录前我们需要创建工程这里为了让大家养成模块化的好习惯我们尽量将代码分成三个文件来写。这里我打开的编译器是 vs 2022在资源管理器的 头文件 中创建 Contact.h 文件此文件作用主要是为了存储各种头文件和通讯录各个功能的函数的声明以及联系人信息和通讯录结构体的创建在源文件中创建 Contact.c 文件用来实现通讯录各大功能的函数Test.c 文件用来测试通讯录的功能。具体如下图所示 ♨️一、静态通讯录 1.1 通讯录的前期准备 1.1.1 创建菜单 再创建通讯录之前我们需要先建立一个完整的菜单从而来实现用户与计算机的交互方便用户快速查找和访问通讯录中的联系人信息以实现快捷拨号、发送短信、查看联系人信息等功能。 代码 void menu() {printf(------------------------------\n);printf(---- 1.添加联系人 ----\n);printf(---- 2.删除联系人 ----\n);printf(---- 3.查找联系人 ----\n);printf(---- 4.修改联系人 ----\n);printf(---- 5.打印通讯录 ----\n);printf(---- 6.排序通讯录 ----\n);printf(---- 0.退出通讯录 ----\n);printf(------------------------------\n); }1.1.2 创建结构体 //类型声明 typedef struct PeoInfo {char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX]; }PeoInfo; //一个联系人的信息typedef struct Contact {PeoInfo data[MAX];//存放联系人的信息int sz;//记录当前通讯录存放的联系人个数 }Contact;//通讯录定义两个结构体类型PeoInfo和Contact。 PeoInfo结构体类型包含了5个成员变量分别是 name一个字符数组用于存储联系人姓名其最大长度为NAME_MAX。age一个整型变量用于存储联系人年龄。sex一个字符数组用于存储联系人性别其最大长度为SEX_MAX。tele一个字符数组用于存储联系人电话号码其最大长度为TELE_MAX。addr一个字符数组用于存储联系人地址其最大长度为ADDR_MAX。 这个结构体类型代表了一个联系人的信息。 Contact结构体类型包含了两个成员变量 data一个PeoInfo类型的数组用于存储多个联系人的信息其最大长度为MAX。sz一个整型变量用于记录当前通讯录中存放的联系人个数。 这个结构体类型代表了一个通讯录其中可以存储多个联系人的信息并且记录了当前通讯录中联系人的个数。 通过这两个结构体类型我们可以方便地存储和管理联系人的信息和通讯录的状态。 1.1.3 头文件的包含和#define定义常量 #includestdio.h #includestring.h//memset、strcmp #includeassert.h//assert #includestdlib.h//qsort函数、malloc、realloc#define NAME_MAX 20 //姓名 #define SEX_MAX 5 //性别 #define TELE_MAX 12 //电话 #define ADDR_MAX 30 //地址 #define MAX 100 //通讯录中可记录联系人数目的最大值1.1.4 接口函数的声明 声明实现通讯录各个功能的函数如初始化通讯录增加联系人显示联系人删除联系人查找联系人等功能的函数。 //初始化通讯录 void InitContact(Contact* pc); //增加联系人 void AddContact(Contact* pc); //显示联系人信息 void ShowContact(Contact* pc);//这里形参也可以是结构体变量因为打印不改变结构体内容 //删除联系人 void DelContact(Contact* pc); //查找联系人 void SearchContact(Contact* pc); //修改指定联系人 void ModifyContact(Contact* pc); //排序通讯录 void SortContact(Contact* pc); //按姓名排序 void SortContact_by_name(Contact* pc); //按年龄排序 void SortContact_by_age(Contact* pc);1.1.5 实现通讯录菜单选项的对接 创建一个通讯录程序的框架为了增加代码的可读性和维护性使用枚举类型定义各个功能函数的选择。在主函数中首先创建了一个通讯录对象并初始化该对象。然后通过一个循环来显示菜单并获取用户的输入根据用户的选择调用相应的函数来执行相应的操作。 enum Option //枚举常量对应各个函数的选择 {EXIT, //0ADD, //1DEL, //2SEARCH, //3MODIFY, //4SHOW, //5SORT //6 };int main() {int input 0;//创建通讯录Contact con;//通讯录//初始化通讯录InitContact(con);int choice 0;//排序方式的选择do{menu();printf(请输入你的选择 -);scanf(%d, input);switch (input){case ADD:AddContact(con);break;case DEL:DelContact(con);break;case SEARCH:SearchContact(con);break;case MODIFY:ModifyContact(con);break;case SHOW:ShowContact(con);break;case SORT:SortContact(con);break;case EXIT: printf(退出通讯录\n); break;default:printf(选择错误请重新选择\n);break;}} while (input);return 0; }1.2 通讯录函数功能的实现 1.2.1 初始化通讯录 //初始化通讯录 void InitContact(Contact* pc) {assert(pc);pc-sz 0;memset(pc-data, 0, sizeof(pc-data)); }首先使用 assert 宏来检查传入的指针是否为非空。如果指针为空则程序会在这里终止并输出错误信息。接下来将结构体的 sz 成员变量初始化为 0这是表示通讯录中联系人数目的变量。然后使用 memset 函数将结构体的 data 成员数组该数组存放的是联系人的信息初始化为 0。sizeof(pc-data) 确定了要清零的字节数确保整个数组都被清零。 1.2.2 添加联系人 //增加联系人 void AddContact(Contact* pc) {assert(pc);if (pc-sz MAX){printf(通讯录已满无法增加\n);return;}//增加信息printf(请输入增加联系人的名字);scanf(%s, pc-data[pc-sz].name);printf(请输入增加联系人的年龄);scanf(%d, (pc-data[pc-sz].age));printf(请输入增加联系人的性别);scanf(%s, pc-data[pc-sz].sex);printf(请输入增加联系人的电话);scanf(%s, pc-data[pc-sz].tele);printf(请输入增加联系人的地址);scanf(%s, pc-data[pc-sz].addr);pc-sz;printf(增加联系人成功!\n); }首先使用断言assert确保传入的指针不为空。然后检查通讯录是否已满即 sz 等于 MAX。如果已满则打印一条错误消息并返回不执行后续操作。如果通讯录未满则提示用户输入要增加的联系人的姓名、年龄、性别、电话和地址。使用 scanf 函数从标准输入读取用户的输入并将其存储在 Contact 结构体中相应的字段中。最后将 sz 的值加 1表示成功增加了一个联系人并打印一条成功消息。 1.2.3 删除联系人 //删除联系人 void DelContact(Contact* pc) {char name[NAME_MAX];assert(pc);if (pc-sz 0){printf(通讯录为空无法删除\n);return;}printf(请输入要删除的人的名字);scanf(%s, name);//找到名字为name的人int ret FindByName(pc, name);if (ret -1){printf(要删除的人不存在\n);return;}//删除这个人的信息for (int i ret; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}pc-sz--;printf(删除成功\n); }首先声明一个字符数组name用于存储要删除的人的名字。使用断言assert确保传入的指针不为空。如果通讯录为空即sz等于0则打印一条错误消息并返回不执行后续操作。提示用户输入要删除的人的名字并将其存储在name数组中。调用FindByName函数来查找名字为name的人的位置将结果存储在变量ret中。如果ret等于-1表示要删除的人不存在则打印一条错误消息并返回。如果找到了要删除的人则通过循环将后面的联系人信息向前移动一位覆盖掉要删除的人的信息。将通讯录的大小减1表示成功删除了一个联系人。打印一条成功消息表示删除成功。 1.2.4 查找联系人 在查找联系人并打印信息之前我们需要先找到联系人的下标以便后续对于该联系人信息的获取和修改等操作。所以先创建一个FindByName 的函数该函数的作用是查找联系人若找到返回联系人的下标否者返回 -1。 1FindByName 函数 //查找联系人并返回下标 int FindByName(Contact* pc, char name[]) {assert(pc);for (int i 0; i pc-sz; i){if (strcmp(name, pc-data[i].name) 0){return i;//找到了返回下标}}return -1;//没找到返回-1 }首先使用assert(pc)确保传入的联系人列表指针不为空。然后使用一个循环遍历联系人列表中的每个元素。循环变量i从 0 开始直到pc-sz - 1联系人列表的大小。在循环中使用strcmp(name, pc-data[i].name) 0判断当前联系人的名称是否与要查找的名称相同。这里使用了strcmp函数进行字符串比较。如果找到了匹配的联系人即strcmp的结果为 0则返回当前下标i。如果循环结束后仍未找到匹配的联系人则返回 -1。 2SearchContact 函数 //查找联系人并打印信息 void SearchContact(Contact* pc) {char name[NAME_MAX];assert(pc);printf(请输入要查找的人的姓名);scanf(%s, name);int ret FindByName(pc, name);if (ret -1){printf(要查找的人不存在\n);return;}//显示找到的人的信息printf(%-5s %-10s %-5s %-5s %-12s %-30s\n, 序号, 姓名, 年龄, 性别, 电话, 地址);printf(%-5d %-10s %-5d %-5s %-12s %-30s\n,ret 1,pc-data[ret].name,pc-data[ret].age,pc-data[ret].sex,pc-data[ret].tele,pc-data[ret].addr); }此函数接受一个指向Contact 结构体的指针作为参数然后提示用户输入要查找的人的姓名。接着调用 FindByName 函数来查找该联系人并将结果存储在变量ret中。如果找到了联系人它会显示该联系人的信息否则它会打印一条错误消息。 1.2.5 修改联系人信息 由于联系人有多个信息我们无法确定要修改的信息是哪一项所以在修改联系人信息前需要先创建一个修改联系人信息的菜单从而供用户选择对相应的信息进行修改。 1ModifyMenu 函数 void ModifyMenu() {printf(------------------------\n);printf(---- 0.退出修改 ----\n);printf(---- 1.修改姓名 ----\n);printf(---- 2.修改年龄 ----\n);printf(---- 3.修改性别 ----\n);printf(---- 4.修改电话 ----\n);printf(---- 5.修改地址 ----\n);printf(------------------------\n); }2ModifyContact 函数 //修改指定联系人 void ModifyContact(Contact* pc) {char name[NAME_MAX];assert(pc);printf(请输入要修改的人的姓名);scanf(%s, name);int ret FindByName(pc, name);if (ret -1){printf(要修改的人不存在\n);return;}int input 0;do{ModifyMenu();//修改信息的菜单printf(请选择你要修改的信息-:);scanf(%d, input);switch (input){case 0:printf(退出修改\n);break;case 1:printf(请输入修改后的姓名);scanf(%s, pc-data[ret].name);break;case 2:printf(请输入修改后的年龄);scanf(%d, (pc-data[ret].age));break;case 3:printf(请输入修改后的性别);scanf(%s, pc-data[ret].sex);break;case 4:printf(请输入修改后的电话);scanf(%s, pc-data[ret].tele);break;case 5:printf(请输入修改后的地址);scanf(%s, pc-data[ret].addr);break;default:printf(选择错误请重新选择\n);break;}} while (input);printf(修改成功\n); }首先通过输入要修改的人的姓名来查找该联系人如果找到了就进入一个循环显示修改信息的菜单并让用户选择要修改的信息然后根据用户的选择进行相应的修改操作。最后输出修改成功的提示信息。 1.2.6 打印通讯录信息 遍历通讯录逐个打印出联系人的序号、姓名、年龄、性别、电话和地址信息。如果通讯录为空则则打印提示信息并结束函数。 //显示联系人信息 void ShowContact(Contact* pc)//这里形参也可以是结构体变量因为打印不改变结构体内容 {assert(pc);if (pc-sz 0){printf(通讯录为空无需打印\n);return;}int i 0;//序号 名字 年龄 性别 电话 地址//xxx xxx xxx xxx xxx xxxprintf(%-5s %-10s %-5s %-5s %-12s %-30s\n, 序号, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i pc-sz; i){//打印每个人的信息printf(%-5d %-10s %-5d %-5s %-12s %-30s\n,i 1, pc-data[i].name, pc-data[i].age, pc-data[i].sex, pc-data[i].tele, pc-data[i].addr);} }1.2.7 排序通讯录 这里可以使用两种方式进行排序第一种是按照联系人姓名排序第二种则是按照联系人年龄来排序。两种排序都是基于 qsort 函数来实现。qsort 函数的具体使用方法见《深入理解回调函数qsort从入门到模拟实现》 qsort 函数的关键是第四个参数该参数是一个函数指针用来指向一个比较函数故排序的方式也是由它来决定的比如想要按姓名来排序就要写一个按姓名来比较的函数如果想要按年龄来排序就要写一个按年龄来比较的函数。 1SortMenu 函数 该函数打印的是通讯录排序的方式方便与用户进行交互让用户来选择排序通讯录的方式。 void SortMenu() {printf(-------------------------\n);printf(---- 0.退出排序 ----\n);printf(---- 1.按姓名排序 ----\n);printf(---- 2.按年龄排序 ----\n);printf(-------------------------\n); }2比较函数 排序函数 //按名字比较 int cmp_by_name(const void* e1, const void* e2) {return strcmp(((PeoInfo*)e1)-name, ((PeoInfo*)e2)-name); }//按年龄比较 int cmp_by_age(const void* e1, const void* e2) {return ((PeoInfo*)e1)-age - ((PeoInfo*)e2)-age; }//按姓名排序 --- qsort void SortContact_by_name(Contact* pc) {qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp_by_name); } //按年龄排序 --- qsort void SortContact_by_age(Contact* pc) {qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp_by_age); }这段代码是用于对联系人进行排序的。它包含了两个比较函数cmp_by_name 和cmp_by_age以及两个排序函数SortContact_by_name 和 SortContact_by_age。 cmp_by_name 函数用于按名字比较两个联系人。它接受两个 const void* 类型的参数 e1 和 e2然后将它们转换为 PeoInfo 类型的指针并使用 strcmp 函数比较它们的 name 成员。如果 e1 的名字在字母顺序上排在 e2 之前则返回负数如果相等则返回零如果 e1 的名字在字母顺序上排在 e2 之后则返回正数。cmp_by_age 函数用于按年龄比较两个联系人。它接受两个 const void* 类型的参数 e1 和 e2然后将它们转换为 PeoInfo 类型的指针并计算它们的 age 成员之差。如果 e1 的年龄小于 e2的年龄则返回负数如果相等则返回零如果 e1 的年龄大于 e2 的年龄则返回正数。SortContact_by_name 函数用于按姓名对联系人数组进行排序。它接受一个 Contact* 类型的参数 pc然后使用 qsort 函数对 pc-data 数组进行排序。qsort 函数的第四个参数是一个比较函数指针这里传入的是 cmp_by_name 函数。这样当 qsort函数需要比较两个元素时就会调用 cmp_by_name 函数来进行比较。SortContact_by_age 函数用于按年龄对联系人数组进行排序。它与 SortContact_by_name 函数类似只是比较函数改为了 cmp_by_age 函数。 3SortContact 函数 //排序通讯录 void SortContact(Contact* pc) {int inpuct 0;if (pc-sz 0){printf(通讯录为空不用排序\n);return;}do{SortMenu();//排序通讯录菜单printf(请选择排序方式 -);scanf(%d, inpuct);switch (inpuct){case 0:printf(退出排序\n);break;case 1:SortContact_by_name(pc);printf(按姓名排序后\n);ShowContact(pc);break;case 2:SortContact_by_age(pc);printf(按年龄排序后\n);ShowContact(pc);break;default:printf(输入错误请重新输入);break;}} while (inpuct); }首先代码检查联系人数组是否为空如果为空则打印提示信息并返回。接下来进入一个循环显示排序菜单并等待用户输入选择。根据用户的输入执行相应的排序操作 如果用户选择0退出排序如果用户选择1调用 SortContact_by_name 函数按姓名对联系人进行排序并打印排序后的结果如果用户选择2调用 SortContact_by_age 函数按年龄对联系人进行排序并打印排序后的结果。 如果用户输入的选择不在有效范围内会打印错误提示并重新显示排序菜单。 1.3 静态通讯录源代码 1.3.1 Contact.h 文件 #pragma once#includestdio.h #includestring.h #includeassert.h #includestdlib.h//qsort函数、malloc、realloc#define NAME_MAX 20 //姓名 #define SEX_MAX 5 //性别 #define TELE_MAX 12 //电话 #define ADDR_MAX 30 //地址 #define MAX 100 //通讯录中可记录联系人数目的最大值//类型声明 typedef struct PeoInfo {char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX]; }PeoInfo; //一个联系人的信息typedef struct Contact {PeoInfo data[MAX];//存放联系人的信息int sz;//记录当前通讯录存放的联系人个数 }Contact;//通讯录//初始化通讯录 void InitContact(Contact* pc);//增加联系人 void AddContact(Contact* pc);//显示联系人信息 void ShowContact(Contact* pc);//这里形参也可以是结构体变量因为打印不改变结构体内容//删除联系人 void DelContact(Contact* pc);//查找联系人 void SearchContact(Contact* pc);//修改指定联系人 void ModifyContact(Contact* pc);//排序通讯录 void SortContact(Contact* pc);//按姓名排序 void SortContact_by_name(Contact* pc);//按年龄排序 void SortContact_by_age(Contact* pc);1.3.2 Contact.c 文件 #define _CRT_SECURE_NO_WARNINGS 1#include Contact.hvoid ModifyMenu() {printf(------------------------\n);printf(---- 0.退出修改 ----\n);printf(---- 1.修改姓名 ----\n);printf(---- 2.修改年龄 ----\n);printf(---- 3.修改性别 ----\n);printf(---- 4.修改电话 ----\n);printf(---- 5.修改地址 ----\n);printf(------------------------\n); }void SortMenu() {printf(-------------------------\n);printf(---- 0.退出排序 ----\n);printf(---- 1.按姓名排序 ----\n);printf(---- 2.按年龄排序 ----\n);printf(-------------------------\n); }//初始化通讯录 void InitContact(Contact* pc) {assert(pc);pc-sz 0;memset(pc-data, 0, sizeof(pc-data)); }//增加联系人 void AddContact(Contact* pc) {assert(pc);if (pc-sz MAX){printf(通讯录已满无法增加\n);return;}//增加信息printf(请输入增加联系人的名字);scanf(%s, pc-data[pc-sz].name);printf(请输入增加联系人的年龄);scanf(%d, (pc-data[pc-sz].age));printf(请输入增加联系人的性别);scanf(%s, pc-data[pc-sz].sex);printf(请输入增加联系人的电话);scanf(%s, pc-data[pc-sz].tele);printf(请输入增加联系人的地址);scanf(%s, pc-data[pc-sz].addr);pc-sz;printf(增加联系人成功!\n); }//显示联系人信息 void ShowContact(Contact* pc)//这里形参也可以是结构体变量因为打印不改变结构体内容 {assert(pc);if (pc-sz 0){printf(通讯录为空无需打印\n);return;}int i 0;//序号 名字 年龄 性别 电话 地址//xxx xxx xxx xxx xxx xxxprintf(%-5s %-10s %-5s %-5s %-12s %-30s\n, 序号, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i pc-sz; i){//打印每个人的信息printf(%-5d %-10s %-5d %-5s %-12s %-30s\n,i 1, pc-data[i].name, pc-data[i].age, pc-data[i].sex, pc-data[i].tele, pc-data[i].addr);} }//查找联系人并返回下标 int FindByName(Contact* pc, char name[]) {assert(pc);for (int i 0; i pc-sz; i){if (strcmp(name, pc-data[i].name) 0){return i;//找到了返回下标}}return -1;//没找到返回-1 }//删除联系人 void DelContact(Contact* pc) {char name[NAME_MAX];assert(pc);if (pc-sz 0){printf(通讯录为空无法删除\n);return;}printf(请输入要删除的人的名字);scanf(%s, name);//找到名字为name的人int ret FindByName(pc, name);if (ret -1){printf(要删除的人不存在\n);return;}//删除这个人的信息for (int i ret; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}pc-sz--;printf(删除成功\n); }//查找联系人并打印信息 void SearchContact(Contact* pc) {char name[NAME_MAX];assert(pc);printf(请输入要查找的人的姓名);scanf(%s, name);int ret FindByName(pc, name);if (ret -1){printf(要查找的人不存在\n);return;}//显示找到的人的信息printf(%-5s %-10s %-5s %-5s %-12s %-30s\n, 序号, 姓名, 年龄, 性别, 电话, 地址);printf(%-5d %-10s %-5d %-5s %-12s %-30s\n,ret 1,pc-data[ret].name,pc-data[ret].age,pc-data[ret].sex,pc-data[ret].tele,pc-data[ret].addr); }//修改指定联系人 void ModifyContact(Contact* pc) {char name[NAME_MAX];assert(pc);printf(请输入要修改的人的姓名);scanf(%s, name);int ret FindByName(pc, name);if (ret -1){printf(要修改的人不存在\n);return;}int input 0;do{ModifyMenu();//修改信息的菜单printf(请选择你要修改的信息-:);scanf(%d, input);switch (input){case 0:printf(退出修改\n);break;case 1:printf(请输入修改后的姓名);scanf(%s, pc-data[ret].name);break;case 2:printf(请输入修改后的年龄);scanf(%d, (pc-data[ret].age));break;case 3:printf(请输入修改后的性别);scanf(%s, pc-data[ret].sex);break;case 4:printf(请输入修改后的电话);scanf(%s, pc-data[ret].tele);break;case 5:printf(请输入修改后的地址);scanf(%s, pc-data[ret].addr);break;default:printf(选择错误请重新选择\n);break;}} while (input);printf(修改成功\n); }//按名字比较 int cmp_by_name(const void* e1, const void* e2) {return strcmp(((PeoInfo*)e1)-name, ((PeoInfo*)e2)-name); }//按年龄比较 int cmp_by_age(const void* e1, const void* e2) {return ((PeoInfo*)e1)-age - ((PeoInfo*)e2)-age; }//按姓名排序 --- qsort void SortContact_by_name(Contact* pc) {qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp_by_name); } //按年龄排序 --- qsort void SortContact_by_age(Contact* pc) {qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp_by_age); }//排序通讯录 void SortContact(Contact* pc) {int inpuct 0;if (pc-sz 0){printf(通讯录为空不用排序\n);return;}do{SortMenu();//排序通讯录菜单printf(请选择排序方式 -);scanf(%d, inpuct);switch (inpuct){case 0:printf(退出排序\n);break;case 1:SortContact_by_name(pc);printf(按姓名排序后\n);ShowContact(pc);break;case 2:SortContact_by_age(pc);printf(按年龄排序后\n);ShowContact(pc);break;default:printf(输入错误请重新输入);break;}} while (inpuct); }1.3.3 test.c 文件 #define _CRT_SECURE_NO_WARNINGS 1 //测试通讯录基本功能#include Contact.hvoid menu() {printf(------------------------------\n);printf(---- 1.添加联系人 ----\n);printf(---- 2.删除联系人 ----\n);printf(---- 3.查找联系人 ----\n);printf(---- 4.修改联系人 ----\n);printf(---- 5.打印通讯录 ----\n);printf(---- 6.排序通讯录 ----\n);printf(---- 0.退出通讯录 ----\n);printf(------------------------------\n); }enum Option //枚举常量对应各个函数的选择 {EXIT, //0ADD, //1DEL, //2SEARCH, //3MODIFY, //4SHOW, //5SORT //6 };int main() {int input 0;//创建通讯录Contact con;//通讯录//初始化通讯录InitContact(con);int choice 0;//排序方式的选择do{menu();printf(请输入你的选择 -);scanf(%d, input);switch (input){case ADD:AddContact(con);break;case DEL:DelContact(con);break;case SEARCH:SearchContact(con);break;case MODIFY:ModifyContact(con);break;case SHOW:ShowContact(con);break;case SORT:SortContact(con);break;case EXIT: printf(退出通讯录\n); break;default:printf(选择错误请重新选择\n);break;}} while (input);return 0; }♨️二、通讯录优化之动态通讯录 上述静态通讯录我们不难发现它的一个致命的缺点在通讯录结构体的创建时我们将通讯录的大小定义为100当通讯录存满100个人的信息时我们如果想要继续存储则会发生越界程序报错因此我们需要优化通讯录使得我们能够手动增加通讯录的大小于是就需要利用动态内存分配来定义通讯录结构体内的联系人数组的大小。 2.1 通讯录结构体的优化 typedef struct Contact {PeoInfo* data;//存放联系人的信息int sz;//当前通讯录存放的联系人的个数int capacity;//当前通讯录的最大容量 }Contact;定义了一个名为Contact的结构体用于表示通讯录。该结构体包含以下成员 PeoInfo* data;指向存放联系人信息的指针。int sz;当前通讯录中存放的联系人的个数。int capacity;当前通讯录的最大容量。 2.2 通讯录初始化函数的优化 使用 malloc 动态开辟联系人数组的空间初始空间大小为 INIT_DATA再使用 memset 将数组中的值都置为0。 //初始化通讯录 void InitContact(Contact* pc) {assert(pc);pc-data (PeoInfo*)malloc(sizeof(PeoInfo) * INIT_DATA);if (pc-data NULL){perror(InitContact-malloc);return;}memset(pc-data, 0, sizeof(pc-data));pc-sz 0;pc-capacity INIT_DATA; }2.3 添加扩容函数 创建一个用于检查并扩容通讯录的函数。它接受一个指向Contact结构体的指针作为参数并根据当前容量和最大容量进行判断是否需要扩容。 如果当前容量等于最大容量那么就会执行以下操作 使用realloc函数对data成员进行重新分配内存空间。新的内存空间大小为原容量加上一个常量ADD_DATA。如果重新分配失败会打印错误信息并返回。如果重新分配成功将新分配的内存地址赋值给data成员并将最大容量增加ADD_DATA。打印增容成功的消息。 如果当前容量没有达到最大容量则不执行任何操作。 //扩容 void CheckCapacity(Contact* pc) {//1.如果满了就增容if (pc-sz pc-capacity){Contact* ptr (PeoInfo*)realloc(pc-data, (pc-capacity ADD_DATA) * sizeof(PeoInfo));if (ptr NULL){perror(CheckCapacity-realloc);return;}pc-data ptr;pc-capacity ADD_DATA;printf(增容成功\n);}//2.如果没满啥也不干 }2.4 释放动态开辟的内存 创建一个销毁通讯录的函数其目的是在程序结束前释放动态开辟的内存空间。它接受一个指向Contact结构体的指针作为参数并执行以下操作 使用free函数释放data成员所指向的内存空间。将data成员设置为NULL以避免悬挂指针。将sz成员设置为0表示当前通讯录中没有联系人。将capacity成员设置为0表示通讯录的最大容量为0。使用printf函数输出销毁通讯录成功的消息。 通过调用这个函数可以释放通讯录所占用的内存空间并将相关成员变量重置为初始状态。 //销毁通讯录 void DestroyContact(Contact* pc) {free(pc-data);pc-data NULL;pc-sz 0;pc-capacity 0;printf(销毁通讯录成功\n); }2.5 动态通讯录源代码 2.5.1 Contact.h 文件 #pragma once#includestdio.h #includestring.h #includeassert.h #includestdlib.h//qsort函数、malloc、realloc#define NAME_MAX 20 //姓名 #define SEX_MAX 5 //性别 #define TELE_MAX 12 //电话 #define ADDR_MAX 30 //地址 //#define MAX 100 //通讯录记录的人的信息的最大值#define INIT_DATA 4 //通讯录的初始大小 #define ADD_DATA 2 //每次通讯录增加的容量大小//类型声明 typedef struct PeoInfo {char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX]; }PeoInfo; //一个人的信息//typedef struct Contact //{ // PeoInfo data[MAX];//存放信息 // int sz;//记录当前通讯录存放的人的信息个数 //}Contact;typedef struct Contact {PeoInfo* data;//存放联系人的信息int sz;//当前通讯录存放的联系人的个数int capacity;//当前通讯录的最大容量 }Contact;//初始化通讯录 void InitContact(Contact* pc);//增加联系人 void AddContact(Contact* pc);//显示联系人信息 void ShowContact(Contact* pc);//这里形参也可以是结构体变量因为打印不改变结构体内容//删除联系人 void DelContact(Contact* pc);//查找联系人 void SearchContact(Contact* pc);//修改指定联系人 void ModifyContact(Contact* pc);//排序通讯录 void SortContact(Contact* pc);//按姓名排序 void SortContact_by_name(Contact* pc);//按年龄排序 void SortContact_by_age(Contact* pc);//销毁通讯录 void DestroyContact(Contact* pc);2.5.2 Contact.c 文件 #define _CRT_SECURE_NO_WARNINGS 1#include Contact.hvoid CheckCapacity(Contact* pc);void ModifyMenu() {printf(------------------------\n);printf(---- 0.退出修改 ----\n);printf(---- 1.修改姓名 ----\n);printf(---- 2.修改年龄 ----\n);printf(---- 3.修改性别 ----\n);printf(---- 4.修改电话 ----\n);printf(---- 5.修改地址 ----\n);printf(------------------------\n); }void SortMenu() {printf(-------------------------\n);printf(---- 0.退出排序 ----\n);printf(---- 1.按姓名排序 ----\n);printf(---- 2.按年龄排序 ----\n);printf(-------------------------\n); }//初始化通讯录 void InitContact(Contact* pc) {assert(pc);pc-data (PeoInfo*)malloc(sizeof(PeoInfo) * INIT_DATA);if (pc-data NULL){perror(InitContact-malloc);return;}memset(pc-data, 0, sizeof(pc-data));pc-sz 0;pc-capacity INIT_DATA; }//扩容 void CheckCapacity(Contact* pc) {//1.如果满了就增容if (pc-sz pc-capacity){Contact* ptr (PeoInfo*)realloc(pc-data, (pc-capacity ADD_DATA) * sizeof(PeoInfo));if (ptr NULL){perror(CheckCapacity-realloc);return;}pc-data ptr;pc-capacity ADD_DATA;printf(增容成功\n);}//2.如果没满啥也不干 }//增加联系人 void AddContact(Contact* pc) {assert(pc);//检查通讯录当前的容量//1.如果满了就增容//2.如果没满啥也不干CheckCapacity(pc);printf(请输入增加联系人的名字);scanf(%s, pc-data[pc-sz].name);printf(请输入增加联系人的年龄);scanf(%d, (pc-data[pc-sz].age));printf(请输入增加联系人的性别);scanf(%s, pc-data[pc-sz].sex);printf(请输入增加联系人的电话);scanf(%s, pc-data[pc-sz].tele);printf(请输入增加联系人的地址);scanf(%s, pc-data[pc-sz].addr);pc-sz;printf(增加联系人成功!\n); }//显示联系人信息 void ShowContact(Contact* pc)//这里形参也可以是结构体变量因为打印不改变结构体内容 {assert(pc);if (pc-sz 0){printf(通讯录为空无需打印\n);return;}int i 0;printf(%-5s %-10s %-5s %-5s %-12s %-30s\n, 序号, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i pc-sz; i){//打印每个人的信息printf(%-5d %-10s %-5d %-5s %-12s %-30s\n,i 1, pc-data[i].name, pc-data[i].age, pc-data[i].sex, pc-data[i].tele, pc-data[i].addr);} }//查找联系人并返回下标 int FindByName(Contact* pc, char name[]) {assert(pc);for (int i 0; i pc-sz; i){if (strcmp(name, pc-data[i].name) 0){return i;//找到了返回下标}}return -1;//没找到返回-1 }//删除联系人 void DelContact(Contact* pc) {char name[NAME_MAX];assert(pc);if (pc-sz 0){printf(通讯录为空无法删除\n);return;}printf(请输入要删除的人的名字);scanf(%s, name);//找到名字为name的人int ret FindByName(pc, name);if (ret -1){printf(要删除的人不存在\n);return;}//删除这个人的信息for (int i ret; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}pc-sz--;printf(删除成功\n); }//查找联系人并打印信息 void SearchContact(Contact* pc) {char name[NAME_MAX];assert(pc);printf(请输入要查找的人的姓名);scanf(%s, name);int ret FindByName(pc, name);if (ret -1){printf(要查找的人不存在\n);return;}//显示找到的人的信息printf(%-5s %-10s %-5s %-5s %-12s %-30s\n, 序号, 姓名, 年龄, 性别, 电话, 地址);printf(%-5d %-10s %-5d %-5s %-12s %-30s\n,ret 1, pc-data[ret].name, pc-data[ret].age, pc-data[ret].sex, pc-data[ret].tele, pc-data[ret].addr); }//修改指定联系人 void ModifyContact(Contact* pc) {char name[NAME_MAX];assert(pc);printf(请输入要修改的人的姓名);scanf(%s, name);int ret FindByName(pc, name);if (ret -1){printf(要修改的人不存在\n);return;}int input 0;do{ModifyMenu();printf(请选择你要修改的信息-:);scanf(%d, input);switch (input){case 0:printf(退出修改\n);break;case 1:printf(请输入修改后的姓名);scanf(%s, pc-data[ret].name);break;case 2:printf(请输入修改后的年龄);scanf(%d, (pc-data[ret].age));break;case 3:printf(请输入修改后的性别);scanf(%s, pc-data[ret].sex);break;case 4:printf(请输入修改后的电话);scanf(%s, pc-data[ret].tele);break;case 5:printf(请输入修改后的地址);scanf(%s, pc-data[ret].addr);break;default:printf(选择错误请重新选择\n);break;}} while (input);printf(修改成功\n); }//按名字比较 int cmp_by_name(const void* e1, const void* e2) {return strcmp(((PeoInfo*)e1)-name, ((PeoInfo*)e2)-name); }//按年龄比较 int cmp_by_age(const void* e1, const void* e2) {return ((PeoInfo*)e1)-age - ((PeoInfo*)e2)-age; }//按姓名排序 void SortContact_by_name(Contact* pc) {qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp_by_name); } //按年龄排序 void SortContact_by_age(Contact* pc) {qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp_by_age); }//排序通讯录 void SortContact(Contact* pc) {int inpuct 0;if (pc-sz 0){printf(通讯录为空不用排序\n);return;}do{SortMenu();printf(请选择排序方式 -);scanf(%d, inpuct);switch (inpuct){case 0:printf(退出排序\n);break;case 1:SortContact_by_name(pc);printf(按姓名排序后\n);ShowContact(pc);break;case 2:SortContact_by_age(pc);printf(按年龄排序后\n);ShowContact(pc);break;default:printf(输入错误请重新输入);break;}} while (inpuct); }//销毁通讯录 void DestroyContact(Contact* pc) {free(pc-data);pc-data NULL;pc-sz 0;pc-capacity 0;printf(销毁通讯录成功\n); }2.5.3 test.c 文件 #define _CRT_SECURE_NO_WARNINGS 1 //测试通讯录基本功能#include Contact.hvoid menu() {printf(------------------------\n);printf(---- 1.add ----\n);printf(---- 2.del ----\n);printf(---- 3.search ----\n);printf(---- 4.modify ----\n);printf(---- 5.show ----\n);printf(---- 6.sorts ----\n);printf(---- 0.exit ----\n);printf(------------------------\n); }enum Option {EXIT, //0ADD,DEL,SEARCH,MODIFY,SHOW,SORT };int main() {int input 0;//创建通讯录Contact con;//通讯录//初始化通讯录InitContact(con);int choice 0;//排序方式的选择do{menu();printf(请输入你的选择 -);scanf(%d, input);switch (input){case EXIT:DestroyContact(con);printf(退出通讯录\n);break;case ADD:AddContact(con);break;case DEL:DelContact(con);break;case SEARCH:SearchContact(con);break;case MODIFY:ModifyContact(con);break;case SHOW:ShowContact(con);break;case SORT:SortContact(con);break;default:printf(选择错误请重新选择\n);break;}} while (input);return 0; }♨️三、通讯录优化之文件版通讯录 在实现动态通讯录后我们发现虽然解决了通讯录空间不足的问题但是对于已经加入通讯录中的信息在退出程序后无法保存来即退出程序后之前添加的联系人信息消失不见无法找到。这是因为程序运行后信息是存储在内存上的退出程序后计算机会清除内存上的信息但是文件中的信息是存储在磁盘上的即使程序退出磁盘上的信息仍然存在不会消失。 所以为了使通讯录中的信息保存下来我们需要采用文件操作的方法实现。 3.1 保存通讯录信息到文件 创建一个函数 SaveContact将通讯录中的数据保存到名为 Contact.text 的文件中。 //保存通讯录中的数据到文件中 void SaveContact(Contact* pc) {FILE* pf fopen(Contact.text, wb);if (pf NULL){perror(SaveContact);return;}//写信息到文件int i 0;for (i 0; i pc-sz; i){//fwrite((pc-data[i]), sizeof(PeoInfo), 1, pf);fwrite(pc-data i, sizeof(PeoInfo), 1, pf);}//关闭文件fclose(pf);pf NULL; }首先使用 fopen 函数以二进制模式打开文件并将文件指针存储在变量 pf 中。如果无法打开文件即 pf 为NULL则会调用 perror 函数打印错误信息并直接返回。接下来代码使用一个循环来遍历通讯录中的每个联系人。循环变量 i 从 0 开始直到 pc-sz通讯录的大小减 1。在每次循环中通过 fwrite 函数将当前联系人的信息写入文件中。这里使用了指针运算符 来获取当前联系人的地址并将其作为第一个参数传递给 fwrite 函数。第二个参数是每个联系人信息的大小单位是字节第三个参数是要写入的次数第四个参数是文件指针。最后代码使用 fclose 函数关闭文件并将文件指针设置为 NULL以确保不会再次使用该指针。 3.2 在初始化时加载文件信息到通讯录 创建一个 LoadContact 函数将文件中的信息加载到通讯录中。在初始化时调用此函数即可将文件 Contact.text 中的信息加载到通讯录中。 //将文件信息加载到通讯录 void LoadContact(Contact* pc) {FILE* pf fopen(Contact.text, rb);if (pf NULL){perror(LoadContact);return;}//加载文件信息读文件PeoInfo temp { 0 }; //临时存储从文件中读取的数据while (fread(temp, sizeof(PeoInfo), 1, pf)) //读取成功返回1否则返回0{//检查容量如果没满才能加载文件中的数据到通讯录CheckCapacity(pc);pc-data[pc-sz] temp;}//关闭文件fclose(pf);pf NULL; }首先使用fopen函数以二进制只读模式打开文件并将文件指针保存在变量pf中。如果文件打开失败函数会调用perror函数打印错误信息并直接返回。接下来函数创建一个临时变量temp并将其初始化为全零。然后它进入一个循环使用fread函数从文件中读取数据每次读取一个PeoInfo结构体的大小。如果读取成功fread函数返回1否则返回0。在循环中函数首先调用CheckCapacity函数来检查通讯录是否还有空间容纳新的联系人信息。如果有空间就将读取到的联系人信息存储到通讯录的相应位置并将通讯录的大小加 1。最后函数使用fclose函数关闭文件并将文件指针设置为 NULL以避免后续操作时出现错误。 3.3 文件版通讯录源代码 3.3.1 Contact.h 文件 #pragma once#includestdio.h #includestring.h #includeassert.h #includestdlib.h //qsort函数、malloc、realloc#define NAME_MAX 20 //姓名 #define SEX_MAX 5 //性别 #define TELE_MAX 12 //电话 #define ADDR_MAX 30 //地址 //#define MAX 100 //通讯录记录的人的信息的最大值#define INIT_DATA 4 //通讯录的初始大小 #define ADD_DATA 2 //每次通讯录增加的容量大小//类型声明 typedef struct PeoInfo {char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX]; }PeoInfo; //一个人的信息//typedef struct Contact //{ // PeoInfo data[MAX];//存放信息 // int sz;//记录当前通讯录存放的人的信息个数 //}Contact;typedef struct Contact {PeoInfo* data;//存放联系人的信息int sz;//当前通讯录存放的联系人的个数int capacity;//当前通讯录的最大容量 }Contact;//初始化通讯录 void InitContact(Contact* pc);//增加联系人 void AddContact(Contact* pc);//显示联系人信息 void ShowContact(Contact* pc);//这里形参也可以是结构体变量因为打印不改变结构体内容//删除联系人 void DelContact(Contact* pc);//查找联系人 void SearchContact(Contact* pc);//修改指定联系人 void ModifyContact(Contact* pc);//排序通讯录 void SortContact(Contact* pc);//按姓名排序 void SortContact_by_name(Contact* pc);//按年龄排序 void SortContact_by_age(Contact* pc);//销毁通讯录 void DestroyContact(Contact* pc);//保存通讯录中的数据到文件中 void SaveContact(Contact* pc);3.3.2 Contact.c 文件 #define _CRT_SECURE_NO_WARNINGS 1#include Contact.h//检查通讯录的容量是否已满 void CheckCapacity(Contact* pc);void ModifyMenu() {printf(------------------------\n);printf(---- 0.退出修改 ----\n);printf(---- 1.修改姓名 ----\n);printf(---- 2.修改年龄 ----\n);printf(---- 3.修改性别 ----\n);printf(---- 4.修改电话 ----\n);printf(---- 5.修改地址 ----\n);printf(------------------------\n); }void SortMenu() {printf(-------------------------\n);printf(---- 0.退出排序 ----\n);printf(---- 1.按姓名排序 ----\n);printf(---- 2.按年龄排序 ----\n);printf(-------------------------\n); }//将文件信息加载到通讯录 void LoadContact(Contact* pc) {FILE* pf fopen(Contact.text, rb);if (pf NULL){perror(LoadContact);return;}//加载文件信息读文件PeoInfo temp { 0 }; //临时存储从文件中读取的数据while (fread(temp, sizeof(PeoInfo), 1, pf)) //读取成功返回1否则返回0{//检查容量如果没满才能加载文件中的数据到通讯录CheckCapacity(pc);pc-data[pc-sz] temp;}//关闭文件fclose(pf);pf NULL; }//文件版本的初始化通讯录 void InitContact(Contact* pc) {assert(pc);pc-data (PeoInfo*)malloc(sizeof(PeoInfo) * INIT_DATA);if (pc-data NULL){perror(InitContact-malloc);return;}memset(pc-data, 0, sizeof(pc-data));pc-sz 0;pc-capacity INIT_DATA;//加载文件中的信息到通讯录LoadContact(pc); }动态版本的初始化通讯录 //void InitContact(Contact* pc) //{ // assert(pc); // pc-data (PeoInfo*)malloc(sizeof(PeoInfo) * INIT_DATA); // if (pc-data NULL) // { // perror(InitContact-malloc); // return; // } // memset(pc-data, 0, sizeof(pc-data)); // pc-sz 0; // pc-capacity INIT_DATA; //}//扩容 void CheckCapacity(Contact* pc) {//1.如果满了就增容if (pc-sz pc-capacity) {Contact* ptr (PeoInfo*)realloc(pc-data, (pc-capacity ADD_DATA) * sizeof(PeoInfo)); if (ptr NULL){perror(CheckCapacity-realloc);return;}pc-data ptr;pc-capacity ADD_DATA;printf(增容成功\n);}//2.如果没满啥也不干 }//增加联系人 void AddContact(Contact* pc) {assert(pc);//检查通讯录当前的容量//1.如果满了就增容//2.如果没满啥也不干CheckCapacity(pc);printf(请输入增加联系人的名字);scanf(%s, pc-data[pc-sz].name);printf(请输入增加联系人的年龄);scanf(%d, (pc-data[pc-sz].age));printf(请输入增加联系人的性别);scanf(%s, pc-data[pc-sz].sex);printf(请输入增加联系人的电话);scanf(%s, pc-data[pc-sz].tele);printf(请输入增加联系人的地址);scanf(%s, pc-data[pc-sz].addr);pc-sz;printf(增加联系人成功!\n); }//显示联系人信息 void ShowContact(Contact* pc)//这里形参也可以是结构体变量因为打印不改变结构体内容 {assert(pc);if (pc-sz 0){printf(通讯录为空无需打印\n);return;}int i 0;printf(%-5s %-10s %-5s %-5s %-12s %-30s\n, 序号, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i pc-sz; i){//打印每个人的信息printf(%-5d %-10s %-5d %-5s %-12s %-30s\n,i 1, pc-data[i].name, pc-data[i].age, pc-data[i].sex, pc-data[i].tele, pc-data[i].addr);} }//查找联系人并返回下标 int FindByName(Contact* pc, char name[]) {assert(pc);for (int i 0; i pc-sz; i){if (strcmp(name, pc-data[i].name) 0){return i;//找到了返回下标}}return -1;//没找到返回-1 }//删除联系人 void DelContact(Contact* pc) {char name[NAME_MAX];assert(pc);if (pc-sz 0){printf(通讯录为空无法删除\n);return;}printf(请输入要删除的人的名字);scanf(%s, name);//找到名字为name的人int ret FindByName(pc, name);if (ret -1){printf(要删除的人不存在\n);return;}//删除这个人的信息for (int i ret; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}pc-sz--;printf(删除成功\n); }//查找联系人并显示联系人的信息 void SearchContact(Contact* pc) {char name[NAME_MAX];assert(pc);printf(请输入要查找的人的姓名);scanf(%s, name);int ret FindByName(pc, name);if (ret -1){printf(要查找的人不存在\n);return;}//显示找到的人的信息printf(%-5s %-10s %-5s %-5s %-12s %-30s\n, 序号, 姓名, 年龄, 性别, 电话, 地址);printf(%-5d %-10s %-5d %-5s %-12s %-30s\n,ret 1,pc-data[ret].name,pc-data[ret].age,pc-data[ret].sex,pc-data[ret].tele,pc-data[ret].addr); }//修改指定联系人 void ModifyContact(Contact* pc) {char name[NAME_MAX];assert(pc);printf(请输入要修改的人的姓名);scanf(%s, name);int ret FindByName(pc, name);if (ret -1){printf(要修改的人不存在\n);return;}int input 0;do{ModifyMenu();printf(请选择你要修改的信息-:);scanf(%d, input);switch (input){case 0:printf(退出修改\n);break;case 1:printf(请输入修改后的姓名);scanf(%s, pc-data[ret].name);break;case 2:printf(请输入修改后的年龄);scanf(%d, (pc-data[ret].age));break;case 3:printf(请输入修改后的性别);scanf(%s, pc-data[ret].sex);break;case 4:printf(请输入修改后的电话);scanf(%s, pc-data[ret].tele);break;case 5:printf(请输入修改后的地址);scanf(%s, pc-data[ret].addr);break;default:printf(选择错误请重新选择\n);break;}} while (input);printf(修改成功\n); }//销毁通讯录 void DestroyContact(Contact* pc) {free(pc-data);pc-data NULL;pc-sz 0;pc-capacity 0; }//按名字比较 int cmp_by_name(const void* e1, const void* e2) {return strcmp(((PeoInfo*)e1)-name, ((PeoInfo*)e2)-name); }//按年龄比较 int cmp_by_age(const void* e1, const void* e2) {return ((PeoInfo*)e1)-age - ((PeoInfo*)e2)-age; }//按姓名排序 void SortContact_by_name(Contact* pc) {qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp_by_name); } //按年龄排序 void SortContact_by_age(Contact* pc) {qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp_by_age); }//排序通讯录 void SortContact(Contact* pc) {int inpuct 0;if (pc-sz 0){printf(通讯录为空不用排序\n);return;}do{SortMenu();printf(请选择排序方式 -);scanf(%d, inpuct);switch (inpuct){case 0:printf(退出排序\n);break;case 1:SortContact_by_name(pc);printf(按姓名排序后\n);ShowContact(pc);break;case 2:SortContact_by_age(pc);printf(按年龄排序后\n);ShowContact(pc);break;default:printf(输入错误请重新输入);break;}} while (inpuct); }//保存通讯录中的数据到文件中 void SaveContact(Contact* pc) {FILE* pf fopen(Contact.text, wb);if (pf NULL){perror(SaveContact);return;}//写信息到文件int i 0;for (i 0; i pc-sz; i){//fwrite((pc-data[i]), sizeof(PeoInfo), 1, pf);fwrite(pc-data i, sizeof(PeoInfo), 1, pf);}//关闭文件fclose(pf);pf NULL; }3.3.3 test.c 文件 #define _CRT_SECURE_NO_WARNINGS 1 //测试通讯录基本功能#include Contact.hvoid menu() {printf(------------------------\n);printf(---- 1.add ----\n);printf(---- 2.del ----\n);printf(---- 3.search ----\n);printf(---- 4.modify ----\n);printf(---- 5.show ----\n);printf(---- 6.sorts ----\n);printf(---- 0.exit ----\n);printf(------------------------\n); }enum Option {EXIT, //0ADD,DEL,SEARCH,MODIFY,SHOW,SORT };int main() {int input 0;//创建通讯录Contact con;//通讯录//初始化通讯录InitContact(con);int choice 0;//排序方式的选择do{menu();printf(请输入你的选择 -);scanf(%d, input);switch (input){case EXIT://保存通讯录中的数据到文件中SaveContact(con);//销毁通讯录DestroyContact(con);printf(退出通讯录\n);break;case ADD:AddContact(con);break;case DEL:DelContact(con);break;case SEARCH:SearchContact(con);break;case MODIFY:ModifyContact(con);break;case SHOW:ShowContact(con);break;case SORT:SortContact(con);break;default:printf(选择错误请重新选择\n);break;}} while (input);return 0; }今天的分享就到此结束了如有疑问或是文章有不足之处还请大家在评论区与我讨论或者私信我创作不易如果文章对你有帮助的话还请三连支持一下咯
文章转载自:
http://www.morning.zzgtdz.cn.gov.cn.zzgtdz.cn
http://www.morning.mnclk.cn.gov.cn.mnclk.cn
http://www.morning.dncgb.cn.gov.cn.dncgb.cn
http://www.morning.saastob.com.gov.cn.saastob.com
http://www.morning.rnmdp.cn.gov.cn.rnmdp.cn
http://www.morning.drswd.cn.gov.cn.drswd.cn
http://www.morning.jxwhr.cn.gov.cn.jxwhr.cn
http://www.morning.rsjng.cn.gov.cn.rsjng.cn
http://www.morning.mcjrf.cn.gov.cn.mcjrf.cn
http://www.morning.lkbdy.cn.gov.cn.lkbdy.cn
http://www.morning.nnttr.cn.gov.cn.nnttr.cn
http://www.morning.zfwjh.cn.gov.cn.zfwjh.cn
http://www.morning.svrud.cn.gov.cn.svrud.cn
http://www.morning.gqryh.cn.gov.cn.gqryh.cn
http://www.morning.xoaz.cn.gov.cn.xoaz.cn
http://www.morning.pctsq.cn.gov.cn.pctsq.cn
http://www.morning.knmby.cn.gov.cn.knmby.cn
http://www.morning.kwwkm.cn.gov.cn.kwwkm.cn
http://www.morning.rppf.cn.gov.cn.rppf.cn
http://www.morning.fbzdn.cn.gov.cn.fbzdn.cn
http://www.morning.nmkbl.cn.gov.cn.nmkbl.cn
http://www.morning.tktcr.cn.gov.cn.tktcr.cn
http://www.morning.wqpb.cn.gov.cn.wqpb.cn
http://www.morning.rpzqk.cn.gov.cn.rpzqk.cn
http://www.morning.yqkxr.cn.gov.cn.yqkxr.cn
http://www.morning.chkfp.cn.gov.cn.chkfp.cn
http://www.morning.wmmtl.cn.gov.cn.wmmtl.cn
http://www.morning.hhqtq.cn.gov.cn.hhqtq.cn
http://www.morning.fqtzn.cn.gov.cn.fqtzn.cn
http://www.morning.mrnnb.cn.gov.cn.mrnnb.cn
http://www.morning.ai-wang.cn.gov.cn.ai-wang.cn
http://www.morning.ltpmy.cn.gov.cn.ltpmy.cn
http://www.morning.nqrlz.cn.gov.cn.nqrlz.cn
http://www.morning.bfsqz.cn.gov.cn.bfsqz.cn
http://www.morning.wplbs.cn.gov.cn.wplbs.cn
http://www.morning.gqfbl.cn.gov.cn.gqfbl.cn
http://www.morning.kdjtt.cn.gov.cn.kdjtt.cn
http://www.morning.rdmz.cn.gov.cn.rdmz.cn
http://www.morning.npmpn.cn.gov.cn.npmpn.cn
http://www.morning.tmzlt.cn.gov.cn.tmzlt.cn
http://www.morning.ykgkh.cn.gov.cn.ykgkh.cn
http://www.morning.hjlwt.cn.gov.cn.hjlwt.cn
http://www.morning.ctpfq.cn.gov.cn.ctpfq.cn
http://www.morning.qwzpd.cn.gov.cn.qwzpd.cn
http://www.morning.sbdqy.cn.gov.cn.sbdqy.cn
http://www.morning.nzsdr.cn.gov.cn.nzsdr.cn
http://www.morning.ffdyy.cn.gov.cn.ffdyy.cn
http://www.morning.kdjtt.cn.gov.cn.kdjtt.cn
http://www.morning.rcntx.cn.gov.cn.rcntx.cn
http://www.morning.rhsr.cn.gov.cn.rhsr.cn
http://www.morning.hwcln.cn.gov.cn.hwcln.cn
http://www.morning.gfpyy.cn.gov.cn.gfpyy.cn
http://www.morning.nwllb.cn.gov.cn.nwllb.cn
http://www.morning.cpljq.cn.gov.cn.cpljq.cn
http://www.morning.qsmmq.cn.gov.cn.qsmmq.cn
http://www.morning.rbkdg.cn.gov.cn.rbkdg.cn
http://www.morning.krgjc.cn.gov.cn.krgjc.cn
http://www.morning.hsdhr.cn.gov.cn.hsdhr.cn
http://www.morning.zfgh.cn.gov.cn.zfgh.cn
http://www.morning.bsbcp.cn.gov.cn.bsbcp.cn
http://www.morning.srbfp.cn.gov.cn.srbfp.cn
http://www.morning.jpbky.cn.gov.cn.jpbky.cn
http://www.morning.dygqq.cn.gov.cn.dygqq.cn
http://www.morning.sgwr.cn.gov.cn.sgwr.cn
http://www.morning.bmfqg.cn.gov.cn.bmfqg.cn
http://www.morning.qcwck.cn.gov.cn.qcwck.cn
http://www.morning.wnjrf.cn.gov.cn.wnjrf.cn
http://www.morning.btns.cn.gov.cn.btns.cn
http://www.morning.krnzm.cn.gov.cn.krnzm.cn
http://www.morning.ckfqt.cn.gov.cn.ckfqt.cn
http://www.morning.xbdd.cn.gov.cn.xbdd.cn
http://www.morning.qtfss.cn.gov.cn.qtfss.cn
http://www.morning.qnbgk.cn.gov.cn.qnbgk.cn
http://www.morning.yprnp.cn.gov.cn.yprnp.cn
http://www.morning.fpzpb.cn.gov.cn.fpzpb.cn
http://www.morning.wmmqf.cn.gov.cn.wmmqf.cn
http://www.morning.dhckp.cn.gov.cn.dhckp.cn
http://www.morning.lmcrc.cn.gov.cn.lmcrc.cn
http://www.morning.ltbwq.cn.gov.cn.ltbwq.cn
http://www.morning.bkjhx.cn.gov.cn.bkjhx.cn
http://www.tj-hxxt.cn/news/281283.html

相关文章:

  • 网站seo推广方案超越时空网上书城网站策划书
  • 国外网站排行榜wordpress 摄影 模板
  • 网站建设公司简介模板wordpress 使用浏览器缓存
  • 淘宝内部卷网站建设深圳宝安区是什么风险
  • 网站导航优化的描述游戏设计网站
  • 公司网站搭建南宁市建设厅网站
  • phpcms 网站路径建设银行大厂支行网站
  • 营销网站建设步骤wordpress表单制作
  • 营销建设网站个人做网站能赚到钱吗
  • 沧州网站优化个人建设网站教程
  • 苏州模板建站定制wordpress 主题 demo
  • 工信部网站备案查询系统joomla网站如何加入会话功能
  • 网站闭站保护做网站空间
  • 网站设计描述114网址大全
  • 合肥知名网站制作公司广阳区建设局网站
  • 网站外链建设培训找我家是做的视频网站
  • flash 网站厦门关键词排名提升
  • 外贸建站与推广如何做手机壳湖北建设网
  • 鞍山企业做网站vshtml5网站开发
  • 西安市未央区建设局官方网站网站12栅格系统怎么做
  • 创建网站英语哪些网站有友情链接
  • 郑州网站建设包括哪些吉林网站建设企业
  • 网站被恶意点击怎么办protected wordpress login
  • 基础网站建设素材甘肃三北防护林建设局网站
  • 网站制作 搜索网站智能建设有那些优势
  • 谷歌优化 网站建设如何选择免费网站建设
  • 自己做第一个网站山东滕州做网站技术电话
  • 上海网站设计工具广州网站建设知名 乐云践新
  • 扬中市建设局网站适合个人开发的小程序创意
  • 网站建设管理情况报告如何将vs做的网站备份出来