c语言实现通讯录
前言
目录
一、通讯录:
1.1 通讯录介绍:
本次通讯录采用 结构体数组 存储 联系人 数据. 结构体数组 的每个成员保存着联系人的具体信息特征. 用一个参数 sz 记录当前联系人个数.
1.2 通讯录功能介绍:
1.添加联系人 2.删除联系人 3.修改联系人 4.查询联系人 5.展示通讯录
效果展示:
二、通讯录的实现:
2.1 通讯录类型的声明:
//宏定义,为了修改时更加方便
#define NAME_MAX 10 //名字的最大长度
#define SEX_MAX 5 //性别的最大长度
#define ADDR_MAX 20 //地址的最大长度
#define N 200 //定义最大存储联系人个数
//创建描述的人结构体类型
typedef struct people
{
char name[NAME_MAX]; //姓名
int age; //年龄
char sex[SEX_MAX]; //性别
float stature; //身高
char addr[ADDR_MAX]; //地址
}peo;
//创建通讯录类型
typedef struct Contact
{
peo data[N];//结构体数组,数组每个成员都是结构体,其中保存着联系人的信息
int sz;//用于记录当前练习人的个数
}Contact;
2.2 通讯录的初始化:
通讯录 的大体框架已经建好,但是那只是通讯录的类型,我们应当利用类型创建变量并进行合理的初始化操作. 定义 通讯录 变量:
Contact cont;//创建通讯录cont
对 通讯录 进行合理的 初始化 操作.
InitContact(Contact* cont)//初始化通讯录函数
{
assert(cont);//防止传入空指针
cont->sz = 0;//初始时.通讯录为空,即0个联系人
memset(cont->data, 0, sizeof(cont->data));//将结构体数组所占内存区域全部初始化为0.
}
2.3 添加联系人函数:
由于这一版本的 通讯录 采用的数组存储信息,数组的大小是 有限的 ,所以在进行添加联系人之前,我们应当考虑此时通讯录是否已经满了,当通讯录已经满了的时候,返回添加失败的错误信息. 否则正常插入,在数组下标sz位置添加联系人信息,最后sz++,表示联系人的个数增加1.
void add(Contact* cont)//添加联系人函数
{
assert(cont);//防止传入空指针
if (cont->sz == N)//如果已有200联系人,则不能添加
{
printf("添加失败,通讯录已满");
return;
}
printf("请输入要添加联系人的信息:\n");
printf("请输入姓名:");
scanf("%s", cont->data[cont->sz].name);
printf("请输入年龄:");
scanf("%d", &cont->data[cont->sz].age);
printf("请输入的性别:");
scanf("%s", cont->data[cont->sz].sex);
printf("请输入身高:");
scanf("%f", &cont->data[cont->sz].stature);
printf("请输入地址:");
scanf("%s", cont->data[cont->sz].addr);
cont->sz++;//人数加一
printf("添加成功\n");
}
2.4 查询指定联系人函数:
为什么先介绍"查询指定联系人函数"呢? 我们知道,后面我们需要实现下列功能
删除联系人 修改联系人
这些功能都需要先找到目标联系人,所以我们先实现这个函数,后续需要在删除联系人和修改联系人时,可以直接调用该函数即可,
为了更好让该函数可以被其他函数复用,我们设计规则是:
该函数如果查找到了指定联系人,则返回该联系人在数组中的下标位置. 如果该联系不存在,则返回一个负数(因为数组的下标不可能是负数).
int FindName(const Contact* cont,const char* name)//查找人函数
{
assert(cont && name);//防止传入空指针
int i = 0;
for (i = 0; i < cont->sz; i++)
{
//注意,字符串的比较不能使用"==",而要借助strcmp函数
if (!strcmp(cont->data[i].name, name))//查找通讯录是否有这个名字
{
return i;//有就返回下标
}
}
return -1;//查找失败,返回一个负数.
}
当然,有时候实际我们需要的查询联系人函数实现的功能不是返回下标,而是,如果存在该联系人,则打印该联系人的信息,没有则打印相应的提示信息.
void sel(const Contact* cont)//查询联系人函数
{
char name[NAME_MAX];
printf("请输入要查询的联系人的名字:\n");
scanf("%s", name);
int ret = FindName(cont, name);//利用查询人函数查找指定联系人的下标
if (ret == -1)//如果返回-1,则查找失败
{
printf("通讯录中没有该联系人,查询失败.\n");
return;
}
printf("查询成功,该联系信息如下:\n");
printf(" +---------------------------------------------------------------+\n");
printf(" |%-10s %-5d %-5s %-7f %-15s |\n", cont->data[ret].name, cont->data[ret].age, cont->data[ret].sex, cont->data[ret].stature, cont->data[ret].addr);
printf(" +---------------------------------------------------------------+\n");
}
2.5 删除联系人函数
删除联系人操作:
1.需要知道该联系所在下标. 2.将该元素后的所有元素向前"移动"(说是移动,其实就是向前覆盖)一步. 3.size–,这样后面的元素其实并没有删除,而是访问不到了.
动态图解:
void del(Contact* cont)//删除联系人函数
{
assert(cont);//防止传入空指针
int i = 0;
char name[NAME_MAX];
printf("请输入需要删除的联系人的姓名:\n");
scanf("%s", name);
i=FindName(cont, name);
if (i == -1)
{
printf("通讯录中没有该联系人,删除失败\n");
return;
}
for (; i < cont->sz-1; i++)//注意这里sz要-1,因为下面用到了i+1下标
{
cont->data[i] = cont->data[i + 1];
}
cont->sz--;
printf("删除成功,姓名为%s的联系人已删除\n", name);
}
2.6 修改指定联系人函数
其实讲到这里,修改指定联系人应该是一个很简单的操作.
1.我们先利用查找人函数,将下标找到. 2.获取要修改后联系人的信息. 3.将该下标位置的联系人信息覆盖为为新的信息.
void mod(Contact* cont)//修改联系人函数
{
assert(cont);//防止传入空指针
int ret = 0;
char name[NAME_MAX];
printf("请输入要修改的联系人的姓名:\n");
scanf("%s", name);
ret = FindName(cont, name);
if (ret == -1)
{
printf("通讯录中没有该联系人,修改失败\n");
return;
}
printf("请输入修改后联系人的信息:\n");
printf("请输入姓名:");
scanf("%s", cont->data[ret].name);
printf("请输入年龄:");
scanf("%d", &cont->data[ret].age);
printf("请输入的性别:");
scanf("%s", cont->data[ret].sex);
printf("请输入身高:");
scanf("%f", &cont->data[ret].stature);
printf("请输入地址:");
scanf("%s", cont->data[ret].addr);
printf("修改成功.\n");
}
总结
此版本的通讯录还有很多方面有待提高. 例如:
1.我们能否动态增长该通讯录的存储容量? 2.能否增加排序等新的功能? 3.能否保存以前的通讯录信息,当我们下次打开通讯录后,通讯录还保存以前的信息. …… 这些优化,会涉及到文件等后需要学习的知识,下回牛牛在细细分解.今天就到这里啦!!
总代码:
主测试区:
#include "声明区.h"
void menu()
{
printf("\n 欢迎使用通讯录:\n");
printf(" +-------------------------------------------------------------+\n");
printf(" | 0.退出通讯录. |\n");
printf(" | 1.添加联系人 2.删除联系人 |\n");
printf(" | 3.修改联系人 4.查询联系人 |\n");
printf(" | 5.展示通讯录 |\n");
printf(" +-------------------------------------------------------------+\n");
printf("请选择:");
}
int main()
{
int input = 0;
Contact cont;//创建通讯录cont
InitContact(&cont);
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 0:
printf("退出通讯录");
break;
case 1:
add(&cont);//添加联系人
break;
case 2:
del(&cont);//删除联系人
break;
case 3:
mod(&cont);//修改联系人
break;
case 4:
sel(&cont);//查询联系人
break;
case 5:
show(&cont);//展示通讯录
break;
default:
printf("输入错误");
break;
}
} while (input);
return 0;
}
函数实现区:
#include "声明区.h"
InitContact(Contact* cont)//初始化通讯录函数
{
assert(cont);//防止传入空指针
cont->sz = 0;
memset(cont->data, 0, sizeof(cont->data));
}
void add(Contact* cont)//添加联系人函数
{
assert(cont);//防止传入空指针
if (cont->sz == N)//如果已有200联系人,则不能添加
{
printf("添加失败,通讯录已满");
return;
}
printf("请输入要添加联系人的信息:\n");
printf("请输入姓名:");
scanf("%s", cont->data[cont->sz].name);
printf("请输入年龄:");
scanf("%d", &cont->data[cont->sz].age);
printf("请输入的性别:");
scanf("%s", cont->data[cont->sz].sex);
printf("请输入身高:");
scanf("%f", &cont->data[cont->sz].stature);
printf("请输入地址:");
scanf("%s", cont->data[cont->sz].addr);
cont->sz++;//人数加一
printf("添加成功\n");
}
void show(const Contact* cont)//展示通讯录函数
{
assert(cont);//防止传入空指针
int i = 0;
printf(" 通讯录\n");
printf(" +---------------------------------------------------------------+\n");
printf(" |姓名 年龄 性别 身高 地址 |\n");
for (i = 0; i < cont->sz; i++)
{
printf(" |%-10s %-5d %-5s %-7f %-15s |\n", cont->data[i].name, cont->data[i].age, cont->data[i].sex, cont->data[i].stature, cont->data[i].addr);
}
printf(" +---------------------------------------------------------------+\n");
}
int FindName(const Contact* cont,const char* name)//查找人函数
{
assert(cont && name);//防止传入空指针
int i = 0;
for (i = 0; i < cont->sz; i++)
{
if (!strcmp(cont->data[i].name, name))//查找通讯录是否有这个名字
{
return i;//有就返回下标
}
}
return -1;//没有返回一个负数.
}
void del(Contact* cont)//删除联系人函数
{
assert(cont);//防止传入空指针
int i = 0;
char name[NAME_MAX];
printf("请输入需要删除的联系人的姓名:\n");
scanf("%s", name);
i=FindName(cont, name);
if (i == -1)
{
printf("通讯录中没有该联系人,删除失败\n");
return;
}
for (; i < cont->sz-1; i++)//注意这里sz要-1,因为下面用到了i+1下标
{
cont->data[i] = cont->data[i + 1];
}
cont->sz--;
printf("删除成功,姓名为%s的联系人已删除\n", name);
}
void mod(Contact* cont)//修改联系人函数
{
assert(cont);//防止传入空指针
int ret = 0;
char name[NAME_MAX];
printf("请输入要修改的联系人的姓名:\n");
scanf("%s", name);
ret = FindName(cont, name);
if (ret == -1)
{
printf("通讯录中没有该联系人,修改失败\n");
return;
}
printf("请输入修改后联系人的信息:\n");
printf("请输入姓名:");
scanf("%s", cont->data[ret].name);
printf("请输入年龄:");
scanf("%d", &cont->data[ret].age);
printf("请输入的性别:");
scanf("%s", cont->data[ret].sex);
printf("请输入身高:");
scanf("%f", &cont->data[ret].stature);
printf("请输入地址:");
scanf("%s", cont->data[ret].addr);
printf("修改成功.\n");
}
void sel(const Contact* cont)//查询联系人函数
{
char name[NAME_MAX];
printf("请输入要查询的联系人的名字:\n");
scanf("%s", name);
int ret = FindName(cont, name);
if (ret == -1)
{
printf("通讯录中没有该联系人,查询失败.\n");
return;
}
printf("查询成功,该联系信息如下:\n");
printf(" +---------------------------------------------------------------+\n");
printf(" |%-10s %-5d %-5s %-7f %-15s |\n", cont->data[ret].name, cont->data[ret].age, cont->data[ret].sex, cont->data[ret].stature, cont->data[ret].addr);
printf(" +---------------------------------------------------------------+\n");
}
函数声明区:
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define NAME_MAX 10
#define SEX_MAX 5
#define ADDR_MAX 20
#define N 200//定义最大存储联系人个数
//创建描述的人结构体类型
typedef struct people
{
char name[NAME_MAX]; //姓名
int age; //年龄
char sex[SEX_MAX]; //性别
float stature; //身高
char addr[ADDR_MAX]; //地址
}peo;
//创建通讯录类型
typedef struct Contact
{
peo data[N];
int sz;
}Contact;
InitContact(Contact *cont);//初始化通讯录
void add(Contact *cont);//声明添加联系人函数
void show(const Contact* cont);//展示通讯录函数
int FindName(const Contact* cont,const char* name);//找人函数
void del(Contact* cont);//删除联系人函数
void mod(Contact* cont);//修改联系人函数
void sel(const Contact* cont);//查询联系人函数
相关文章
- 用c语言实现二叉树层序遍历
- 模拟实现银行家算法c语言
- 快速排序(Java语言实现)
- R语言用igraph对上海公交巴士路线数据进行复杂网络、网络图可视化|数据分享
- c语言实现香农编码和译码_香农编码码长
- 使用jna调用c语言动态库对接华视电子身份证阅读机
- Linux下c语言多线程编程
- c语言中strstr函数怎么实现_c语言strstr函数怎么写
- SM4加密算法(JAVA语言实现)
- R语言聚类分析(1)
- Go 语言 errgroup 库的使用方式和实现原理
- R语言生存分析的实现
- R语言预测期货波动率的实现:ARCH与HAR-RV与GARCH,ARFIMA模型比较|附代码数据
- 基于重排序的新量化方法RPTQ:实现大型语言模型的 3 比特量化
- Go语言函数类型实现接口——把函数作为接口来调用
- Go语言字符串截取(获取字符串的某一段字符)
- Go语言网络爬虫多重读取器的实现
- 通信Linux C语言串口通信实现方案研究(linuxc语言串口)
- 使用R语言连接Redis,实现高效大数据管理(r连接redis)
- PHP实现根据浏览器跳转不同语言页面代码
- c语言实现的hashtable分享