用C语言模拟一个通讯录可以用来存储1000个人的信息
每个人的信息包括:
姓名、电话、性别、住址、年龄
功能包括:
- 新增联系人
- 删除联系人
- 查找联系人
- 修改联系人
- 展示所有联系人
- 以名字排序所有联系人
注:此版本完全是小白版本,只用了C语言常规的东西,后续将会进行更新2.0/3.0 等版本
文章末尾有原码哦
目录
一、通讯录菜单
二.下面来看一下用来测试通讯录的主函数
三.声明联系人及通讯录
(一)声明联系人
(二)声明通讯录
四.初始化通讯录
五.一些符号声明
六.通讯录六大功能的具体实现
(一)add(新增联系人)
(二)search(查找联系人)
(三)del (删除联系人)
(四)modify (修改联系人)
(五)show (显示所有联系人)
(六)sort (按姓名排序所有联系人)
七、完整代码
(一)用来测试的 text.c(我创建的文件名)
(二)头文件及各个函数的声明 Contact.h(我创建的文件名)
(三)函数具体的实现 Contact.c(我创建的文件名)
任何一个功能性的用具都会有菜单,通讯录当然也不例外,所以,我们先来设计一个菜单
代码如下:
void menu()
{
printf("************************************\n");
printf("****** 1. add 2. del ******\n");
printf("****** 3. search 4. modify ******\n");
printf("****** 5. show 6. sort ******\n");
printf("****** 0. exit ******\n");
printf("************************************\n");
}
下面看一下效果:
代码如下:
int main()
{
int input = 0;
//创建通讯录 con
Contact con;
//初始化通讯录
InitContact(&con);
do
{
menu();
printf("请选择-> ");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con);//添加联系人
break;
case 2:
DelContact(&con);
break;
case 3:
SearchContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
SortContact(&con);
ShowContact(&con);
break;
case 0:
break;
default:
printf("请重新选择->\n ");
break;
}
} while (input);
return 0;
}
这里为了更易于操作,我们用到了结构体
typedef struct PeoInfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char addr[ADDR_MAX];
char tele[TELE_MAX];
}PeoInfo;
//通讯录信息
typedef struct Contact
{
PeoInfo data[MAX];//用于存放联系人的信息
int sz;//记录通讯录里的人数
}Contact;
我们定义好通讯录之后,就要先对通讯录进行初始化
//初始化通讯录
void InitContact(Contact* pc)
{
assert(pc);
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
//这里使用 memset 函数对数组进行初始化,相比遍历数组,更快,更方便
}
引用全局变量更容易修改,同时在这里说一下,后面内容出现的符号就不显得唐突
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
//添加联系人
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].addr);
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].tele);
pc->sz++;
printf("添加成功\n");
}
在添加新的联系人前,要判断通讯录里的人是否已经满了,如果已经满了,就不能再添加了
看一下效果
为什么先说这一个呢?原因很简单,我们在删除、修改联系人的时候,都要先查找一下,如果有这个人,我们在接着做,没有,就退出
同时,这里我把查找人的具体实现单独写成了一个函数,就是为了方便后续功能的使用
查找人的具体实现:
//查找人的具体实现
int FindByName(const Contact* pc, char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
查找联系人:
//查找联系人
void SearchContact(const Contact* pc)
{
assert(pc);
char name[NAME_MAX] = { 0 };
printf("请输入要查找的人的名字: ");
scanf("%s", name);
int pos = FindByName(pc, name);//这里,把查找名字写成一个单独函数,以便后续改进和其它模块使用
if (-1 == pos)
{
printf("查无此人\n");
return;
}
printf("找到了,信息如下: \n");
printf("%-14s\t%-4s\t%-5s\t%-14s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
printf("%-14s\t%-4d\t%-5s\t%-14s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].addr,
pc->data[pos].tele);
}
看一下效果:
//删除联系人
void DelContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX] = { 0 };
if (pc->sz == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
//先找到被删除的人
printf("请输入要删除的人的名字:>");
scanf("%s", name);
int ret = FindByName(pc, name);
if (-1 == ret)
{
printf("要删除的人不存在\n");
return;
}
//删除
int i = 0;
//这里采用的删除方式是用后面的覆盖前面的
for (i = ret; i < pc->sz-1; i++)// i+1 要小于100,所以sz-1
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
这里就先进行了查找,用到了前面的查找函数
看一下效果:
//修改联系人
void ModifyContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX] = { 0 };
printf("请输入要修改的人的名字:>");
scanf("%s", name);
int pos = FindByName(pc, name);
if (-1 == pos)
{
printf("要修改的人不存在\n");
return;
}
printf("请输入名字:>");
scanf("%s", pc->data[pos].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pos].age));
printf("请输入性别:>");
scanf("%s", pc->data[pos].sex);
printf("请输入地址:>");
scanf("%s", pc->data[pos].addr);
printf("请输入电话:>");
scanf("%s", pc->data[pos].tele);
printf("修改完成\n");
}
这里我们先 查找 刚刚被我们删除的 张三,来看一下确定有这个人存在函数的必要性
我们新增一个人,然后再把他修改成 张三,效果如下:
//展示联系人
void ShowContact(Contact* pc)
{
assert(pc);
int i = 0;
printf("%-14s\t%-4s\t%-5s\t%-14s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-14s\t%-4d\t%-5s\t%-14s\t%-12s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].addr,
pc->data[i].tele);
}
}
下面来看一下,看我们的通讯录中是不是只有张三
果然,只有张三
这里的排序就相当于字典里的那种排序方式,我是采用的冒泡排序来实现的
//排序,这里采用的是冒泡排序
void SortContact(Contact* pc)
{
assert(pc);
PeoInfo temp;//创建一个“通讯录信息”变量,用于交换
int i = 0;
int j = 0;
for (i = 0; i < pc->sz-1; i++)
{
for (j = 0; j < pc->sz - 1 - i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
temp = pc->data[j + 1];
pc->data[j + 1] = pc->data[j];
pc->data[j] = temp;
}
}
}
printf("排序完成,新的顺序如下\n");
}
这里,我新添加 李四、王二麻子 来看一下排序的效果
可以看出,顺序是正确的
这里,我是用的三个文件来写的,各自分开,方面管理
#include "Contact.h"
void menu()
{
printf("************************************\n");
printf("****** 1. add 2. del ******\n");
printf("****** 3. search 4. modify ******\n");
printf("****** 5. show 6. sort ******\n");
printf("****** 0. exit ******\n");
printf("************************************\n");
}
int main()
{
int input = 0;
//创建通讯录 con
Contact con;
//初始化通讯录
InitContact(&con);
do
{
menu();
printf("请选择-> ");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con);//添加联系人
break;
case 2:
DelContact(&con);
break;
case 3:
SearchContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
SortContact(&con);
ShowContact(&con);
break;
case 0:
break;
default:
printf("请重新选择->\n ");
break;
}
} while (input);
return 0;
}
#include
#include
#include
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
//此目录下为声明
//人的信息
typedef struct PeoInfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char addr[ADDR_MAX];
char tele[TELE_MAX];
}PeoInfo;
//通讯录信息
typedef struct Contact
{
PeoInfo data[MAX];//用于存放联系人的信息
int sz;//记录通讯录里的人数
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//添加联系人
void AddContact(Contact* pc);
//展示联系人
void ShowContact(Contact* pc);
//查找联系人
void SearchContact(const Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//修改联系人
void ModifyContact(Contact* pc);
//排序,按照字典那种排序方式
void SortContact(Contact* pc);
#include "Contact.h"
//此目录下为通讯录的具体实现
//初始化通讯录
void InitContact(Contact* pc)
{
assert(pc);
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
//这里使用 memset 函数对数组进行初始化,相比遍历数组,更快,更方便
}
//添加联系人
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].addr);
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].tele);
pc->sz++;
printf("添加成功\n");
}
//展示联系人
void ShowContact(Contact* pc)
{
assert(pc);
int i = 0;
printf("%-14s\t%-4s\t%-5s\t%-14s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-14s\t%-4d\t%-5s\t%-14s\t%-12s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].addr,
pc->data[i].tele);
}
}
//查找人的具体实现
int FindByName(const Contact* pc, char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
//查找联系人
void SearchContact(const Contact* pc)
{
assert(pc);
char name[NAME_MAX] = { 0 };
printf("请输入要查找的人的名字: ");
scanf("%s", name);
int pos = FindByName(pc, name);//这里,把查找名字写成一个单独函数,以便后续改进和其它模块使用
if (-1 == pos)
{
printf("查无此人\n");
return;
}
printf("找到了,信息如下: \n");
printf("%-14s\t%-4s\t%-5s\t%-14s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
printf("%-14s\t%-4d\t%-5s\t%-14s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].addr,
pc->data[pos].tele);
}
//删除联系人
void DelContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX] = { 0 };
if (pc->sz == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
//先找到被删除的人
printf("请输入要删除的人的名字:>");
scanf("%s", name);
int ret = FindByName(pc, name);
if (-1 == ret)
{
printf("要删除的人不存在\n");
return;
}
//删除
int i = 0;
//这里采用的删除方式是用后面的覆盖前面的
for (i = ret; i < pc->sz-1; i++)// i+1 要小于100,所以sz-1
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
//修改联系人
void ModifyContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX] = { 0 };
printf("请输入要修改的人的名字:>");
scanf("%s", name);
int pos = FindByName(pc, name);
if (-1 == pos)
{
printf("要修改的人不存在\n");
return;
}
printf("请输入名字:>");
scanf("%s", pc->data[pos].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pos].age));
printf("请输入性别:>");
scanf("%s", pc->data[pos].sex);
printf("请输入地址:>");
scanf("%s", pc->data[pos].addr);
printf("请输入电话:>");
scanf("%s", pc->data[pos].tele);
printf("修改完成\n");
}
//排序,这里采用的是冒泡排序
void SortContact(Contact* pc)
{
assert(pc);
PeoInfo temp;//创建一个“通讯录信息”变量,用于交换
int i = 0;
int j = 0;
for (i = 0; i < pc->sz-1; i++)
{
for (j = 0; j < pc->sz - 1 - i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
temp = pc->data[j + 1];
pc->data[j + 1] = pc->data[j];
pc->data[j] = temp;
}
}
}
printf("排序完成,新的顺序如下\n");
}
好了,以上就是这个简单通讯录的雏形了,制作不易,希望给位长按收藏,来个免费的三连,后续等小编学习了新知识,就会来完善这个通讯录,我们不见不散!