当前位置:网站首页>用C实现三种版本的通讯录
用C实现三种版本的通讯录
2022-07-19 05:03:00 【发烧的CPU】
目录
据标题所述,本文将详细讲解三种版本通讯录的写法,分别是:
静态的版本;动态的版本;文件的版本。
首先讲解静态版本的写法:
通讯录里含有人的信息,包括名字、年龄、性别、电话、地址。
其中需要实现的功能有:
a.存放若干个人的信息
b.增加联系人
c.删除指定联系人
d.查找联系人
e.修改联系人
f.排序
g.显示联系人
通讯录程序将要新建三个文件,两个源文件,一个头文件,各文件作用如下:
整体思路:
首先在头文件中自定义一个结构体类型(表示人的信息),再自定义一个结构体类型(表示通讯录),在源文件test.c中首先初始化通讯录,再建立一个do while循环,选择语句switch中分别包含增、删、查、改、显示、排序、销毁7种功能选择,于是再在源文件contact.c中写出各功能的自定义函数,整体思路就是这样。
步骤解析:
首先在contact.h中创建人的信息结构体,通讯录结构体:
#define MAX 100//假设通讯录最多存放100人
#define NAME 10
#define SEX 4
#define PHONE 20
#define ADDRESS 30
//人的信息
typedef struct people
{
char name[NAME];
int age;
char sex[SEX];
char phone[PHONE];
char address[ADDRESS];
}people;
//通讯录的信息
typedef struct contact
{
people data[MAX];//结构体数组存放100个人的信息
int count;//记录当前通讯录中实际人的个数
}contact;
在test.c中写出程序的主体来:
void menu()
{
printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
printf("$$$$$$$$$$$ 1.increase 2.delete $$$$$$$$$$\n");
printf("$$$$$$$$$$$ 3.seek 4.correct $$$$$$$$$$\n");
printf("$$$$$$$$$$$ 5.display 6.sort $$$$$$$$$$\n");
printf("$$$$$$$$$$$ 0.exit $$$$$$$$$$\n");
printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
}
enum option
{
exit,
increase,
delete,
seek,
correct,
display,
sort,
};
int main()
{
int input = 0;
contact con;//用结构体类型contact定义一个变量con
//初始化通讯录
initcontact(&con);
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case increase:
increasecontact(&con);
break;
case delete:
deletecontact(&con);
break;
case seek:
seekcontact(&con);
break;
case correct:
correctcontact(&con);
break;
case display:
displaycontact(&con);
break;
case sort:
sortcontact(&con);
break;
case exit:
exitcontact(&con);
printf("退出通讯录\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
在contact.c中写出实现各功能的自定义函数,函数声明写在头文件contact.h中:
各自定义函数如下:
初始化通讯录
void initcontact(contact* p)
{
assert(p);
p->count = 0;
memset(p->data, 0, sizeof(p->data));
}
增加通讯录中的联系人
void increasecontact(contact* p)
{
assert(p);
if (p->count == MAX)
{
printf("通讯录人员已满,无法添加\n");
return;
}
printf("请输入名字:>");
scanf("%s", p->data[p->count].name);
printf("请输入年龄:>");
scanf("%d", &(p->data[p->count].age));
printf("请输入性别:>");
scanf("%s", p->data[p->count].sex);
printf("请输入电话:>");
scanf("%s", p->data[p->count].phone);
printf("请输入地址:>");
scanf("%s", p->data[p->count].address);
p->count++;
printf("增加成功\n");
}
删除通讯录中的联系人
static int find_name(contact* p, char* name)
{
assert(p);
int i = 0;
for (i = 0; i < p->count; i++)
{
if (0 == strcmp(p->data[i].name, name))
{
return i;
}
}
return -1;
}
void deletecontact(contact* p)
{
char name[NAME] = { 0 };
assert(p);
if (p->count == 0)
{
printf("通讯录为空,没有信息可供删除\n");
return;
}
printf("请输入要删除人的名字:>");
scanf("%s", name);
//开始删除
//先查找
int person = find_name(p, name);
if (person == -1)
{
printf("待删除的人不存在\n");
return;
}
//删除
int i = 0;
for (i = 0; i < p->count - 1; i++)
{
p->data[i] = p->data[i + 1];
}
p->count--;
printf("删除成功\n");
}
显示通讯录中的联系人
void displaycontact(contact* p)
{
assert(p);
printf("%-15s\t%-15s\t%-15s\t%-15s\t%-15s\n", "名字", "年龄", "性别", "电话", "地址");
int i = 0;
for (i = 0; i < p->count; i++)
{
printf("%-15s\t%-15d\t%-15s\t%-15s\t%-15s\t", p->data[i].name, p->data[i].age, p->data[i].sex, p->data[i].phone, p->data[i].address);
}
}
查找通讯录中的联系人
void seekcontact(contact* p)
{
assert(p);
char name[NAME] = { 0 };
printf("请输入待查找人的名字:>");
scanf("%s", name);
//查找
int person = find_name(p, name);
if (person == -1)
{
printf("待查找的人不存在\n");
return;
}
//打印
printf("%-15s\t%-15s\t%-15s\t%-15s\t%-15s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-15s\t%-15d\t%-15s\t%-15s\t%-15s\n", p->data[person].name, p->data[person].age, p->data[person].sex, p->data[person].phone, p->data[person].address);
}
修改通讯录中的联系人
void correctcontact(contact* p)
{
assert(p);
char name[NAME] = { 0 };
printf("请输入待修改人的名字:>");
scanf("%s", name);
int person = find_name(p, name);
if (person == -1)
{
printf("待修改的人不存在\n");
return;
}
printf("待修改的人信息已经查到,接下来开始修改\n");
//修改
printf("请输入名字:>");
scanf("%s", p->data[person].name);
printf("请输入年龄:>");
scanf("%s", &(p->data[person].age));
printf("请输入性别:>");
scanf("%s", p->data[person].sex);
printf("请输入电话:>");
scanf("%s", p->data[person].phone);
printf("请输入地址:>");
scanf("%s", p->data[person].address);
printf("修改成功\n");
}
排序通讯录中的联系人
int strcmp_name(const void* e1, const void* e2)
{
return strcmp(((people*)e1)->name, ((people*)e2)->name);
}
void sortcontact(contact* p)
{
assert(p);
qsort(p->data, p->count, sizeof(people), strcmp_name);
printf("排序成功\n");
}
销毁通讯录
void exitcontact(contact* p)
{
assert(p);
initcontact(p);
printf("通讯录人员已清空\n");
}
细节说明:本程序首先需要思路明确,然后要掌握字符串函数strcmp,memset等的使用,及qsort函数的使用。
动态版本通讯录的实现:
动态版本在静态的基础上修改主要有三处:
结构体通讯录中需要加一个成员变量,即通讯录的容量
//动态版本通讯录
typedef struct contact
{
people* data;//存放人的信息
int count;//记录当前通讯录中实际人的个数
int capacity;//当前通讯录的容量
}contact;
初始化通讯录函数需要更改
//初始化通讯录动态版本
int initcontact(contact* p)
{
assert(p);
p->count = 0;
p->data = (people*)calloc(num, sizeof(people));
if (p->data == NULL)
{
printf("initcontact::%s\n", strerror(erron));
return 1;
}
p->capacity = num;
return 0;
}
void exitcontact(contact* p)
{
assert(p);
free(p->data);
p->data = NULL;
}
增加联系人函数需要更改
void increasecapacity(contact* p)
{
if (p->count == p->capacity)
{
people* ptr = (people*)realloc(p->data, (p->capacity + s) * sizeof(people));
if (ptr == NULL)
{
printf("increasecontact::%s\n", strerror(errno));
return;
}
else
{
p->data = ptr;
p->capacity += s;
printf("增容成功\n");
}
}
}
//动态的版本
void increasecontact(contact* p)
{
assert(p);
//增容
increasecapacity(p);
printf("请输入名字:>");
scanf("%s", p->data[p->count].name);
printf("请输入年龄:>");
scanf("%d", &(p->data[p->count].age));
printf("请输入性别:>");
scanf("%s", p->data[p->count].sex);
printf("请输入电话:>");
scanf("%s", p->data[p->count].phone);
printf("请输入地址:>");
scanf("%s", p->data[p->count].address);
p->count++;
printf("增加成功\n");
}
文件版本通讯录的实现:
文件版本的通讯录只需在动态版本通讯录基础上增加两个功能:即保存和加载通讯录的信息。
test.c需做修改的地方:
case exit:
SaveContact(&con);
exitcontact(&con);
printf("退出通讯录\n");
break;
contact.h头文件中需要再多自定义两个函数:
//保存通讯录的信息到文件
void SaveContact(const Contact* pc);
//加载文件的信息到通讯录
void LoadContact(Contact* pc);
相应地,contact.c中需要写出自定义函数程序来:
保存通讯录的信息到文件
void LoadContact(Contact* pc)
{
FILE* pfRead = fopen("contact.txt", "rb");
if (pfRead == NULL)
{
perror("LoadContact");
return;
}
PeoInfo tmp = { 0 };
while (fread(&tmp, sizeof(PeoInfo), 1, pfRead) == 1)
{
CheckCapacity(pc);
pc->data[pc->count] = tmp;
pc->count++;
}
fclose(pfRead);
pfRead = NULL;
}
加载文件的信息到通讯录
void SaveContact(const Contact* pc)
{
assert(pc);
FILE* pfWrite = fopen("contact.txt", "wb");
if (pfWrite == NULL)
{
perror("SaveContact");
return;
}
//写文件-二进制的形式
int i = 0;
for (i = 0; i < pc->count; i++)
{
fwrite(pc->data+i, sizeof(PeoInfo), 1, pfWrite);
}
fclose(pfWrite);
pfWrite = NULL;
}
本次分享到此结束,后续会有不断更新,不要忘记一键三连噢~
边栏推荐
- The pit that wechat payment stepped on in those years
- MySQL gets the start time and end time of the current day, yesterday, this week, last week, this month and last month
- JSON数据开发
- 第七十五篇:学术论文写作技巧
- 地址栏输入www.baidu.com之后
- idea svn主干合并分支版本Missing ranges异常Error:svn: E195016
- Hualu Cup - Jiangsu illegal advertising detection - champion summary
- 21 eigenvalues and eigenvectors
- 全局异常统一处理
- 什么是多线程
猜你喜欢
Openwrt manually installs the netdata plug-in
第七十四篇:机器学习优化方法及超参数设置综述
MySQL数据通过SQL查询指定数据表的字段名及字段备注
FreeMarker视图集成
Jenkins linked flybook pushes the test report notification message in the form of signature verification
Redis geographic algorithm geo analysis and Application
Yolov5 realizes smoking behavior detection
Pytorch 目标分类比赛入门
[yolov5 realizes mobile phone detection]
MySQL ten million level sub table optimization
随机推荐
Idea SVN trunk merge branch version missing ranges exception error:svn: e195016
YOLOv5苹果香蕉检测
Zabbix-Sender 增加自定义监控项-- Ping 到目的地链路监控--bat脚本循环运行
第七十四篇:机器学习优化方法及超参数设置综述
Serialization concept learning
Input text to automatically generate images, it's so fun!
ZABBIX agent adds a user-defined monitoring item -- Ping to destination IP link monitoring
The micro engine system runs abnormally in production
YOLOv5飞鸟检测
. Net core uses imagesharp to generate pictures
Jenkins重启后项目丢失 (含 jenkins plugins下载地址)
URL地址映射配置
Yolov5 bird detection
局域网访问项目注意事项
STM32-仿真调试时的SystemInit陷阱
剑指offer 矩阵中的路径
JWT(JSON Web Token)的基础使用
Pytorch 目标分类比赛入门
STM32-点灯程序
那些年微信支付踩过的坑