网站后台如何做下载连接,计算机编程培训班,齐鲁人才网招聘网,90数字设计前言#xff1a;在大多数高校内#xff0c;都是通过设计一个通讯录管理系统来作为c语言课程设计#xff0c;通过一个具体的系统设计将我们学习过的结构体和函数等知识糅合起来#xff0c;可以很好的锻炼学生的编程思维#xff0c;本文旨在为通讯录管理系统的设计提供思路和… 前言在大多数高校内都是通过设计一个通讯录管理系统来作为c语言课程设计通过一个具体的系统设计将我们学习过的结构体和函数等知识糅合起来可以很好的锻炼学生的编程思维本文旨在为通讯录管理系统的设计提供思路和示例讲解并且对如何将数据合理的用文件的形式进行保存进行了讲解和完整代码展示完整代码放在文章末尾 目录
一.非文件操作版本
头文件部分Contact.h
函数实现部分Contact.cpp
主函数部分test.cpp
二.文件的生成
选择何种方式写文件
SaveContact
三.文件数据的读取
LoadContact
四.运行结果截图
五.完整代码
头文件部分Contact.h
函数实现部分Contact.cpp
主函数部分test.cpp 关于通讯录管理系统笔者一共设计了3套分别是最基础的版本动态管理内存版本文件操作版本本文是在动态管理的通讯录管理系统上进行改进如果对于普通的通讯录管理系统有什么不懂的地方可以参考笔者的前俩篇文章里面有详细的万字解读大家也可以根据自己的需求提取完整代码 c语言通讯录管理系统增删查改 c语言通讯录管理系统动态分配内存版 一.非文件操作版本
这里我们给出不包含文件操作版本的代码然后本文后续内容都是基于此进行改进 我们分为 3 个文件来设计 Contact.h 包含头文件的声明对函数的声明以及宏的申明Contact.cpp 通讯录管理系统中具体每一个函数的实现test.cpp 主函数根据用户的选择进行调用相应的函数 头文件部分Contact.h
#pragma once
#pragma once
#includestdio.h
#includeassert.h
#includestring.h
#includestdlib.h#define Name_Max 20
#define Tel_Number 12
#define Sex_Max 5
#define Address_Max 30
#define Contact_Max 100
#define Contact_SZ 3//联系人结构体
typedef struct PeopleInformation
{char name[Name_Max];char telnumber[Tel_Number];int age;char sex[Sex_Max];char address[Address_Max];
}PeoInfor;//通讯录结构体
typedef struct Contact
{PeoInfor* data;//结构体数组存放联系人结构体int size;//记录当前通讯录中有多少个联系人int capacity;//记录当前存放的容量
}Contact;//目录
void menu();//初始化通讯录
void InitContact(Contact* cp);//增加联系人
void AddContact(Contact* cp);//删除联系人
void DelContact(Contact* cp);//通过姓名进行查找联系人
int FindPeople(Contact* cp, char name[]);//展示全部通讯录信息
void ShowContact(const Contact* cp);//查询联系人
void SeachPeople(Contact* cp);//修改联系人信息
void ModifyContact(Contact* cp);//扩容
void CheckContact(Contact* cp);//销毁通讯录
void DestoryContact(Contact* cp);
函数实现部分Contact.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include Contact.hvoid menu()
{printf(\n);printf(-----------------------------\n);printf(--- 1.添加联系人 -----\n);printf(--- 2.删除联系人 -----\n);printf(--- 3.查找联系人 -----\n);printf(--- 4.修改联系人信息 -----\n);printf(--- 5.显示全部信息 -----\n);printf(--- 0.退出通讯录 -----\n);printf(-----------------------------\n);
}//初始化通讯录
void InitContact(Contact* cp)
{//判断非空assert(cp);cp-size 0;cp-capacity Contact_SZ;cp-data (PeoInfor*)calloc(cp-capacity, sizeof(PeoInfor));if (cp-data NULL){perror(InitContact-calloc);return;}
}void CheckContact(Contact* cp)
{if (cp-size cp-capacity){PeoInfor* ptr (PeoInfor*)realloc(cp-data, (cp-capacity 2) * sizeof(PeoInfor));if (ptr ! NULL){cp-data ptr;cp-capacity 2;printf(增容成功\n);}else{perror(AddContact-realloc);return;}}
}//增加联系人
void AddContact(Contact* cp)
{//判断非空assert(cp);//判断满后扩容CheckContact(cp);printf(请输入要添加的联系人的姓名\n);scanf(%s, cp-data[cp-size].name);printf(请输入要添加的联系人的电话号\n);scanf(%s, cp-data[cp-size].telnumber);printf(请输入要添加的联系人的年龄\n);scanf(%d, (cp-data[cp-size].age));printf(请输入要添加的联系人的性别\n);scanf(%s, cp-data[cp-size].sex);printf(请输入要添加的联系人的住址\n);scanf(%s, cp-data[cp-size].address);cp-size;printf(添加成功\n);
}//通过姓名进行查找联系人
int FindPeople(Contact* cp, char name[])
{assert(cp);for (int i 0; i cp-size; i){if (strcmp(cp-data[i].name, name) 0){return i;}}return -1;
}//删除联系人
void DelContact(Contact* cp)
{assert(cp);char name[Name_Max];if (cp-size 0){printf(通讯录为空无需删除\n);return;}printf(请输入选择删除的联系人的姓名\n);scanf(%s, name);int ret FindPeople(cp, name);if (ret -1){printf(要删除的联系人不存在\n);return;}for (int i ret; i cp-size - 1; i){cp-data[i] cp-data[i 1];}cp-size--;printf(删除成功\n);
}//查询联系人
void SeachPeople(Contact* cp)
{assert(cp);char name[Name_Max];if (cp-size 0){printf(通讯录为空\n);return;}printf(请输入选择查找的联系人的姓名\n);scanf(%s, name);int ret FindPeople(cp, name);if (ret -1){printf(要查找的联系人不存在\n);return;}//名字 年龄 性别 电话 地址//xxx xxx xxx xxx xxxprintf(%-10s%-5s%-5s%-12s%-30s\n, 名字, 年龄, 性别, 电话, 地址);//打印个人的信息printf(%-10s%-5d%-5s%-12s%-30s\n, cp-data[ret].name, cp-data[ret].age, cp-data[ret].sex, cp-data[ret].telnumber, cp-data[ret].address);
}//展示全部通讯录信息
void ShowContact(const Contact* cp)
{assert(cp);if (cp-size 0){printf(通讯录为空\n);return;}//名字 年龄 性别 电话 地址//xxx xxx xxx xxx xxxprintf(%-10s%-5s%-5s%-12s%-30s\n, 名字, 年龄, 性别, 电话, 地址);for (int i 0; i cp-size; i){//打印每个人的信息printf(%-10s%-5d%-5s%-12s%-30s\n, cp-data[i].name, cp-data[i].age, cp-data[i].sex, cp-data[i].telnumber, cp-data[i].address);}
}//修改联系人信息
void ModifyContact(Contact* cp)
{assert(cp);char name[Name_Max];if (cp-size 0){printf(通讯录为空\n);return;}printf(请输入选择修改的联系人的姓名\n);scanf(%s, name);int ret FindPeople(cp, name);if (ret -1){printf(要修改的联系人信息不存在\n);return;}printf(请输入要修改的联系人的姓名\n);scanf(%s, cp-data[ret].name);printf(请输入要修改的联系人的电话号\n);scanf(%s, cp-data[ret].telnumber);printf(请输入要修改的联系人的年龄\n);scanf(%d, (cp-data[ret].age));printf(请输入要修改的联系人的性别\n);scanf(%s, cp-data[ret].sex);printf(请输入要修改的联系人的住址\n);scanf(%s, cp-data[ret].address);printf(修改成功\n);
}//销毁通讯录
void DestoryContact(Contact* cp)
{free(cp-data);cp-data NULL;cp-size 0;cp-capacity 0;
}主函数部分test.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include Contact.h//枚举增加程序的可读性
enum options
{EXIT,ADD,DEL,SEACH,MODIFY,SHOW
};int main()
{int input 0;//创建通讯录Contact con;//初始化通讯录InitContact(con);do{menu();printf(请输入你的选择 );scanf(%d, input);switch (input){//增加联系人信息case ADD:AddContact(con);break;//删除联系人信息case DEL:DelContact(con);break;//查找某个联系人的信息case SEACH:SeachPeople(con);break;//修改某个联系人的信息case MODIFY:ModifyContact(con);break;//展示通讯录内的每一个联系人的信息case SHOW:ShowContact(con);break;//退出通讯录管理系统case EXIT:DestoryContact(con);printf(通讯录已退出\n);break;//预防非法输入default:printf(输入错误请重新输入\n);break;}} while (input);return 0;
}
二.文件的生成 想要把通讯录里的数据保存在文件中首先就得生成一个文件但生成文件的思路应该注意以下笔者给大家提供俩个思路
写入一个数据就生成文件如果文件已生成那就写入文件在用户使用完通讯录后一次性将所有数据写入 大家可以思考哪种思路更高效很显然频繁的打开写入关闭文件是不利于我们执行程序的因此我们选择第二条思路当然第一条思路也是可行的在某些特定的需求下可能第一条思路还要更优秀一点但是作为一般讲我们还是希望程序运行所需的时间和空间越简单越好 因此本文采取第二种生成文件的思路在用户使用完通讯录后一次性将所有数据写入也就是说我们需要在用户使用完通讯录程序以后选择退出通讯录的时候进行生成文件并且将通讯录中的数据导入
因此我们封装一个函数来生成通讯录文件
//读取文件信息到通讯录
void LoadContact(Contact* cp);
选择何种方式写文件 我们的通讯录管理系统中有字符串有整形还可能有浮点型短整形结构体类型等等复杂的数据类型因此单一的某中写入方式必然是不在我们考虑范围内的针对我们的需求我们需要选择一个 “万金油” 的写入方式————二进制写入 不管是整形浮点型字符串我们使用二进制去读取写入都是通用的因此后文中对通讯录文件的读取也是使用的二进制读取
SaveContact
我们可以这样设计 首先我们先打开文件如果打开失败那就报错提醒如果正确打开了那我们就进行写入文件使用一个循环一共有多少个联系人信息我们就写入多少次每次写入一个联系人的信息写入完成后关闭文件并且把指针置为空避免造成野指针的问题 //生成文件保存通讯录中的数据
void SaveContact(Contact* cp)
{//打开文件FILE* pf fopen(contact.txt, wb);if (pf NULL){perror(SaveContact);return;}//写文件for (int i 0; i cp-size; i){fwrite(cp-data i, sizeof(PeoInfor), 1, pf);}//关闭文件fclose(pf);pf NULL;
}
三.文件数据的读取 光有文件的生成是不够的假如文件内部已经存了许多联系人的信息了当我们打开通讯录管理系统的时候这些数据也应该已经被读取了才合理 因此我们将文件数据的读取放在通讯录的初始化部分
我们封装一个函数来帮助我们实现这部分功能
//读取文件信息到通讯录
void LoadContact(Contact* cp); 当我们打开通讯录管理系统后首先进行初步的初始化通讯录然后我们将文件中的数据读取到里面
//初始化通讯录
void InitContact(Contact* cp)
{//判断非空assert(cp);//初步初始化cp-size 0;cp-capacity Contact_SZ;cp-data (PeoInfor*)calloc(cp-capacity, sizeof(PeoInfor));if (cp-data NULL){perror(InitContact-calloc);return;}//读取文件信息到通讯录LoadContact(cp);
}LoadContact
为了对应我们前面用二进制写入文件这里我们就应该使用二进制读取文件 //打开文件FILE* pf fopen(contact.txt, rb);if (pf NULL){perror(LoadContact);return;} 我们构建一个结构体数组的临时变量我们先将数据从文件读出来一个然后再判断通讯录是否已经满了如果满了那就先扩容然后再把临时变量中的数据放入通讯录中如果没有满那就直接放入通讯录
//读取文件信息到通讯录
void LoadContact(Contact* cp)
{//打开文件FILE* pf fopen(contact.txt, rb);if (pf NULL){perror(LoadContact);return;}//读取文件PeoInfor temp { 0 };while (fread(temp, sizeof(PeoInfor), 1, pf)){CheckContact(cp);cp-data[cp-size] temp;cp-size;}
}
其中判断扩容函数如下
//检查扩容
void CheckContact(Contact* cp)
{if (cp-size cp-capacity){PeoInfor* ptr (PeoInfor*)realloc(cp-data, (cp-capacity 2) * sizeof(PeoInfor));if (ptr ! NULL){cp-data ptr;cp-capacity 2;printf(增容成功\n);}else{perror(AddContact-realloc);return;}}
}
四.运行结果截图
我们先输入4个人的信息然后退出程序 观察文件因为我们使用的是二进制保存而记事本使用的是 UTF-8 的格式故而这里无法直观看到信息信息相当于被加密了但是可以确定的是我们确实是将数据保存下来了 然后我们重新再打开一遍程序可以看见数据一开始就增容成功读取到了 后续再进行增删查改等操作也是没有影响的 五.完整代码
头文件部分Contact.h
#pragma once
#includestdio.h
#includeassert.h
#includestring.h
#includestdlib.h#define Name_Max 20
#define Tel_Number 12
#define Sex_Max 5
#define Address_Max 30
#define Contact_Max 100
#define Contact_SZ 3//联系人结构体
typedef struct PeopleInformation
{char name[Name_Max];char telnumber[Tel_Number];int age;char sex[Sex_Max];char address[Address_Max];
}PeoInfor;//通讯录结构体
typedef struct Contact
{PeoInfor* data;//结构体数组存放联系人结构体int size;//记录当前通讯录中有多少个联系人int capacity;//记录当前存放的容量
}Contact;//目录
void menu();//初始化通讯录
void InitContact(Contact* cp);//增加联系人
void AddContact(Contact* cp);//删除联系人
void DelContact(Contact* cp);//通过姓名进行查找联系人
int FindPeople(Contact* cp, char name[]);//展示全部通讯录信息
void ShowContact(const Contact* cp);//查询联系人
void SeachPeople(Contact* cp);//修改联系人信息
void ModifyContact(Contact* cp);//jia扩容
void CheckContact(Contact* cp);//销毁通讯录
void DestoryContact(Contact* cp);//生成文件保存通讯录中的数据
void SaveContact(Contact* cp);//读取文件信息到通讯录
void LoadContact(Contact* cp);
函数实现部分Contact.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include Contact.hvoid menu()
{printf(\n);printf(-----------------------------\n);printf(--- 1.添加联系人 -----\n);printf(--- 2.删除联系人 -----\n);printf(--- 3.查找联系人 -----\n);printf(--- 4.修改联系人信息 -----\n);printf(--- 5.显示全部信息 -----\n);printf(--- 0.退出通讯录 -----\n);printf(-----------------------------\n);
}//读取文件信息到通讯录
void LoadContact(Contact* cp)
{//打开文件FILE* pf fopen(contact.txt, rb);if (pf NULL){perror(LoadContact);return;}//读取文件PeoInfor temp { 0 };while (fread(temp, sizeof(PeoInfor), 1, pf)){CheckContact(cp);cp-data[cp-size] temp;cp-size;}
}//初始化通讯录
void InitContact(Contact* cp)
{//判断非空assert(cp);//初步初始化cp-size 0;cp-capacity Contact_SZ;cp-data (PeoInfor*)calloc(cp-capacity, sizeof(PeoInfor));if (cp-data NULL){perror(InitContact-calloc);return;}//读取文件信息到通讯录LoadContact(cp);
}//检查扩容
void CheckContact(Contact* cp)
{if (cp-size cp-capacity){PeoInfor* ptr (PeoInfor*)realloc(cp-data, (cp-capacity 2) * sizeof(PeoInfor));if (ptr ! NULL){cp-data ptr;cp-capacity 2;printf(增容成功\n);}else{perror(AddContact-realloc);return;}}
}//增加联系人
void AddContact(Contact* cp)
{//判断非空assert(cp);//判断满后扩容CheckContact(cp);printf(请输入要添加的联系人的姓名\n);scanf(%s, cp-data[cp-size].name);printf(请输入要添加的联系人的电话号\n);scanf(%s, cp-data[cp-size].telnumber);printf(请输入要添加的联系人的年龄\n);scanf(%d, (cp-data[cp-size].age));printf(请输入要添加的联系人的性别\n);scanf(%s, cp-data[cp-size].sex);printf(请输入要添加的联系人的住址\n);scanf(%s, cp-data[cp-size].address);cp-size;printf(添加成功\n);
}//通过姓名进行查找联系人
int FindPeople(Contact* cp, char name[])
{assert(cp);for (int i 0; i cp-size; i){if (strcmp(cp-data[i].name, name) 0){return i;}}return -1;
}//删除联系人
void DelContact(Contact* cp)
{assert(cp);char name[Name_Max];if (cp-size 0){printf(通讯录为空无需删除\n);return;}printf(请输入选择删除的联系人的姓名\n);scanf(%s, name);int ret FindPeople(cp, name);if (ret -1){printf(要删除的联系人不存在\n);return;}for (int i ret; i cp-size - 1; i){cp-data[i] cp-data[i 1];}cp-size--;printf(删除成功\n);
}//查询联系人
void SeachPeople(Contact* cp)
{assert(cp);char name[Name_Max];if (cp-size 0){printf(通讯录为空\n);return;}printf(请输入选择查找的联系人的姓名\n);scanf(%s, name);int ret FindPeople(cp, name);if (ret -1){printf(要查找的联系人不存在\n);return;}//名字 年龄 性别 电话 地址//xxx xxx xxx xxx xxxprintf(%-10s%-5s%-5s%-12s%-30s\n, 名字, 年龄, 性别, 电话, 地址);//打印个人的信息printf(%-10s%-5d%-5s%-12s%-30s\n, cp-data[ret].name, cp-data[ret].age, cp-data[ret].sex, cp-data[ret].telnumber, cp-data[ret].address);
}//展示全部通讯录信息
void ShowContact(const Contact* cp)
{assert(cp);if (cp-size 0){printf(通讯录为空\n);return;}//名字 年龄 性别 电话 地址//xxx xxx xxx xxx xxxprintf(%-10s%-5s%-5s%-12s%-30s\n, 名字, 年龄, 性别, 电话, 地址);for (int i 0; i cp-size; i){//打印每个人的信息printf(%-10s%-5d%-5s%-12s%-30s\n, cp-data[i].name, cp-data[i].age, cp-data[i].sex, cp-data[i].telnumber, cp-data[i].address);}
}//修改联系人信息
void ModifyContact(Contact* cp)
{assert(cp);char name[Name_Max];if (cp-size 0){printf(通讯录为空\n);return;}printf(请输入选择修改的联系人的姓名\n);scanf(%s, name);int ret FindPeople(cp, name);if (ret -1){printf(要修改的联系人信息不存在\n);return;}printf(请输入要修改的联系人的姓名\n);scanf(%s, cp-data[ret].name);printf(请输入要修改的联系人的电话号\n);scanf(%s, cp-data[ret].telnumber);printf(请输入要修改的联系人的年龄\n);scanf(%d, (cp-data[ret].age));printf(请输入要修改的联系人的性别\n);scanf(%s, cp-data[ret].sex);printf(请输入要修改的联系人的住址\n);scanf(%s, cp-data[ret].address);printf(修改成功\n);
}//销毁通讯录
void DestoryContact(Contact* cp)
{free(cp-data);cp-data NULL;cp-size 0;cp-capacity 0;
}//生成文件保存通讯录中的数据
void SaveContact(Contact* cp)
{//打开文件FILE* pf fopen(contact.txt, wb);if (pf NULL){perror(SaveContact);return;}//写文件for (int i 0; i cp-size; i){fwrite(cp-data i, sizeof(PeoInfor), 1, pf);}//关闭文件fclose(pf);pf NULL;
}
主函数部分test.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include Contact.h//枚举增加程序的可读性
enum options
{EXIT,ADD,DEL,SEACH,MODIFY,SHOW
};int main()
{int input 0;//创建通讯录Contact con;//初始化通讯录InitContact(con);do{menu();printf(请输入你的选择 );scanf(%d, input);switch (input){//增加联系人信息case ADD:AddContact(con);break;//删除联系人信息case DEL:DelContact(con);break;//查找某个联系人的信息case SEACH:SeachPeople(con);break;//修改某个联系人的信息case MODIFY:ModifyContact(con);break;//展示通讯录内的每一个联系人的信息case SHOW:ShowContact(con);break;//退出通讯录管理系统case EXIT:SaveContact(con);DestoryContact(con);printf(通讯录已退出\n);break;//预防非法输入default:printf(输入错误请重新输入\n);break;}} while (input);return 0;
} 本次分享就到此为止了感谢您的支持如有错误欢迎积极指正