前不久刚学完结构体,那么我们来使用结构体来写一个简单的通讯录吧。
文章目录
一.通讯录功能
框架准备
我们创建三个文件。
contact.c - 功能函数的定义
contact.h - 功能函数的声明以及通讯录信息
test.c-通讯录逻辑的实现
在contact.h中创建结构体通讯录,以及联系人结构体
//头文件的使用
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define MAX_NAME 20//名字的最大长度
#define MAX_SEX 5 //性别最大长度
#define MAX_TELE 12//电话最大长度
#define MAX_ADDRESS 30//地址最大长度
#define MAX_CAPACITY 100//联系人容量
//人的信息
typedef struct PeoInfor
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char address[MAX_ADDRESS];
}PeoInfor;
//通讯录
typedef struct Contact
{
int count;//表示当前人数
PeoInfor data[MAX_CAPACITY];
}Contact;
上述名字等信息,我们用#define来定义输入的大小,后期方便修改,同时Contact结构体中,我们定义联系人结构体数组用来存储联系人信息,头文件的作用后面会讲
通讯录逻辑的实现
int main()
{
int input = 0;
Contact pc;//通讯录变量
InitialPeoInfor(&pc);
do
{
menu();
printf("请指示: >");
scanf("%d", &input);
switch (input)
{
case 1:
AddPeoInfor(&pc);
break;
case 2:
DivPeoInfor(&pc);
break;
case 3:
SearchPeoInfor(&pc);
break;
case 4:
ModifyPeoInfor(&pc);
break;
case 5:
ShowPeoInfor(&pc);
break;
case 6:
SortPeoInfor(&pc);
break;
case 0:
printf("已安全退出通讯录\n");
break;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (input);
return 0;
}
功能菜单的打印
//功能菜单
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");
}
初始化通讯录
初始化通讯录我们要把count置为0->表示此时通讯录里面还没有联系人,同时要把data数组初始化为0,这里我们使用memset来初始化每一个联系人为0,需要头文件<string.h>
在contact.h中书写初始化通讯录函数的定义,contact.c中写函数定义
contact.h
//通讯录的初始化
void InitialPeoInfor(Contact* pc);
contact.c
//初始化通讯录
void InitialPeoInfor(Contact* pc)
{
assert(pc);
pc->count = 0;
int i = 0;
for (i = 0; i < MAX_CAPACITY; i++)
{
//void * memset ( void * ptr, int value, size_t num );
//ptr-->代表要设置的地址
//value -->表示要设置元素的值
//num --> 表示要设置每个元素的大小
//data+i 表示每一位的首地址
memset(pc->data+i, 0, sizeof(PeoInfor));
}
}
增加联系人
接下来每一个函数我们都要在contact.h中声明,在contact.c中定义,以及在test.c中引用,下面就不再说明了
contact.h
//增加联系人
void AddPeoInfor(Contact* pc);
contact.c
//增加联系人
void AddPeoInfor(Contact* pc)
{
assert(pc);
printf("请输入联系人姓名: ");
scanf("%s", pc->data[pc->count].name);
printf("请输入联系人年龄: ");
scanf("%d", &(pc->data[pc->count].age));
printf("请输入联系人性别: ");
scanf("%s", pc->data[pc->count].sex);
printf("请输入联系人电话: ");
scanf("%s", pc->data[pc->count].tele);
printf("请输入联系人地址: ");
scanf("%s", pc->data[pc->count].address);
printf("添加成功\n");
pc->count++;//每次我们添加完联系人后,都要把count++一下,
//count表示我们存到第几位了
}
删除联系人
删除联系人我们要查找联系人的位置,这里删除与查找很相似,所以我们定义一个FindPeo函数来查找联系人的位置,这个函数删除与查找是共用的。
FindPeo函数
int FindPeo(Contact* pc, const char* name)
{
int i = 0;
for (i = 0; i < pc->count; i++)
{
//如果找到了我们想要的联系人姓名就返回此时的位置
if (strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
return - 1;
}
contact.h
//删除联系人
void DivPeoInfor(Contact* pc);
contact.c
//删除联系人
void DivPeoInfor(Contact* pc)
{
assert(pc);
if (pc->count <= 0)
{
printf("暂无联系人,请添加联系人\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入想要删除的联系人姓名: ");
scanf("%s", name);
int ret = FindPeo(pc, name);
if (ret < 0)
{
printf("联系人不存在\n");
return;
}
int i = 0;
for (i = ret+1; i < pc->count; i++)
{
pc->data[i - 1] = pc->data[i];
}
pc->count--;
printf("删除成功\n");
}
查找联系人
查找联系人也需要上面的FindPeo函数,这里我们就不再粘了哈,如果找到了我们就把信息打印出来
contact.h
//查找联系人
void SearchPeoInfor(Contact* pc);
contact.c
//查找联系人
void SearchPeoInfor(Contact* pc)
{
assert(pc);
if (pc->count <= 0)
{
printf("暂无联系人,请添加联系人\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入想要查找的联系人姓名: ");
scanf("%s", name);
int pos = FindPeo(pc, name);
if (pos < 0)
{
printf("联系人不存在\n");
return;
}
//这里为了输出好看一点,我们控制一下输出格式
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].address);
}
修改联系人信息
修改联系人还是需要FindPeo函数,这几步的功能实现有很多相似之处,修改完之后我们还是把信息打印出来。
contact.h
//修改联系人
void ModifyPeoInfor(Contact* pc);
contact.c
//修改联系人
void ModifyPeoInfor(Contact* pc)
{
assert(pc);
if (pc->count <= 0)
{
printf("暂无联系人,请添加联系人\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入想要修改的联系人姓名: ");
scanf("%s", name);
int pos = FindPeo(pc, name);
if (pos < 0)
{
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].tele);
printf("请输入联系人地址: ");
scanf("%s", pc->data[pos].address);
printf("修改成功\n");
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].address);
}
显示联系人
contact.h
//展示联系人
void ShowPeoInfor(Contact* pc);
contact.c
//展示联系人
void ShowPeoInfor(Contact* pc)
{
assert(pc);
if (pc->count <= 0)
{
printf("暂无联系人,请添加联系人\n");
return;
}
int i = 0;
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
for (i = 0; i < pc->count; i++)
{
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].address);
}
}
对联系人进行排序
contact.h
//排序联系人(名字)
void SortPeoInfor(Contact* pc);
contact.c
这里排序我们使用qsort函数
void qsort (void* base, size_t num, size_t size,
int (cmp)(const void,const void*));
qsort可以排序任意类型的数据,只不过cmp函数需要自己写
base – 数据名
num --元素个数
size --元素大小
cmp --比较函数
qsort本质起始就是一个排序,cmp是比较函数,排序里面我们传入两个地址,比较的是后size个字节的内容,如果e1>e2就返回1表示大于,此时说明e1指向的元素大于e2指向的元素,所以就交换
//排序联系人
int cmp_byname(const void* e1, const void* e2)
{
return strcmp(((PeoInfor*)e1)->name, ((PeoInfor*)e2)->name);
}
void SortPeoInfor(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->count, sizeof(PeoInfor), cmp_byname);
printf("排序成功\n");
}
总代码
contact.c功能函数的定义
#define _CRT_SECURE_NO_WARNINGS
#include "contact.h"
//功能函数的定义
//初始化通讯录
void InitialPeoInfor(Contact* pc)
{
assert(pc);
pc->count = 0;
int i = 0;
for (i = 0; i < MAX_CAPACITY; i++)
{
memset(pc->data+i, 0, sizeof(PeoInfor));
}
}
//增加联系人
void AddPeoInfor(Contact* pc)
{
assert(pc);
printf("请输入联系人姓名: ");
scanf("%s", pc->data[pc->count].name);
printf("请输入联系人年龄: ");
scanf("%d", &(pc->data[pc->count].age));
printf("请输入联系人性别: ");
scanf("%s", pc->data[pc->count].sex);
printf("请输入联系人电话: ");
scanf("%s", pc->data[pc->count].tele);
printf("请输入联系人地址: ");
scanf("%s", pc->data[pc->count].address);
printf("添加成功\n");
pc->count++;
}
//展示联系人
void ShowPeoInfor(Contact* pc)
{
assert(pc);
if (pc->count <= 0)
{
printf("暂无联系人,请添加联系人\n");
return;
}
int i = 0;
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
for (i = 0; i < pc->count; i++)
{
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].address);
}
}
int FindPeo(Contact* pc, const char* name)
{
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
return - 1;
}
//删除联系人
void DivPeoInfor(Contact* pc)
{
assert(pc);
if (pc->count <= 0)
{
printf("暂无联系人,请添加联系人\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入想要删除的联系人姓名: ");
scanf("%s", name);
int ret = FindPeo(pc, name);
if (ret < 0)
{
printf("联系人不存在\n");
return;
}
int i = 0;
for (i = ret+1; i < pc->count; i++)
{
pc->data[i - 1] = pc->data[i];
}
pc->count--;
printf("删除成功\n");
}
//查找联系人
void SearchPeoInfor(Contact* pc)
{
assert(pc);
if (pc->count <= 0)
{
printf("暂无联系人,请添加联系人\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入想要查找的联系人姓名: ");
scanf("%s", name);
int pos = FindPeo(pc, name);
if (pos < 0)
{
printf("联系人不存在\n");
return;
}
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].address);
}
//修改联系人
void ModifyPeoInfor(Contact* pc)
{
assert(pc);
if (pc->count <= 0)
{
printf("暂无联系人,请添加联系人\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入想要修改的联系人姓名: ");
scanf("%s", name);
int pos = FindPeo(pc, name);
if (pos < 0)
{
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].tele);
printf("请输入联系人地址: ");
scanf("%s", pc->data[pos].address);
printf("修改成功\n");
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].address);
}
//排序联系人
int cmp_byname(const void* e1, const void* e2)
{
return strcmp(((PeoInfor*)e1)->name, ((PeoInfor*)e2)->name);
}
void SortPeoInfor(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->count, sizeof(PeoInfor), cmp_byname);
printf("排序成功\n");
}
contact.h 功能函数的声明
#pragma once
//功能函数的声明
//头文件的使用
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDRESS 30
#define MAX_CAPACITY 100
//人的信息
typedef struct PeoInfor
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char address[MAX_ADDRESS];
}PeoInfor;
//通讯录
typedef struct Contact
{
int count;//表示当前人数
PeoInfor data[MAX_CAPACITY];
}Contact;
//通讯录的初始化
void InitialPeoInfor(Contact* pc);
//增加联系人
void AddPeoInfor(Contact* pc);
//展示联系人
void ShowPeoInfor(Contact* pc);
//删除联系人
void DivPeoInfor(Contact* pc);
//查找联系人
void SearchPeoInfor(Contact* pc);
//修改联系人
void ModifyPeoInfor(Contact* pc);
//排序联系人(名字)
void SortPeoInfor(Contact* pc);
test.c 逻辑的实现
#define _CRT_SECURE_NO_WARNINGS
#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;
Contact pc;//通讯录变量
InitialPeoInfor(&pc);
do
{
menu();
printf("请指示: >");
scanf("%d", &input);
switch (input)
{
case 1:
AddPeoInfor(&pc);
break;
case 2:
DivPeoInfor(&pc);
break;
case 3:
SearchPeoInfor(&pc);
break;
case 4:
ModifyPeoInfor(&pc);
break;
case 5:
ShowPeoInfor(&pc);
break;
case 6:
SortPeoInfor(&pc);
break;
case 0:
printf("已安全退出通讯录\n");
break;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (input);
return 0;
}
效果展示
增加联系人
删除与查找联系人
修改联系人
排序
二.结 言
这次我们使用结构体写了一个通讯录,这只是最初版本,等后期学了动态内存与文件操作时我们就可以动态的开辟通讯录的容量,同时联系人的信息也可以进行保存。