欢迎光临
各位大帅哥,大美女如果觉得文章对自己有帮助
建议:我们可以分模块,我这里就分了三个模块,test.c用于专门测试通讯录功能,contact.c和contact.h用于接口的实现和接口的声明
一个简单的通讯录可以用来:
存储1000个人的信息
每个人的基本信息主要是:姓名、电话、年龄、地址、性别……
如果你想要添加别的信息也可以。
通讯录功能:
1、添加联系人
2、查找联系人
3、删除联系人
4、查看所有联系人
5、修改联系人信息
6、按名字排序
相关的函数接口
//初始化通讯录
void Initcontact(contact* pa);
//增加联系人的信息
void Addcontact(contact* pa);
//删除指定联系人的信息
void Delcontact(contact* pa);
//打印通讯录中的信息
void Printcontact(contact* pa);
//查找指定联系人信息
void Searchcontact(const contact* pa);
//按字典顺序排序
void Sortcontact(contact* pa);
//修改指定联系人的信息
void Modifycontact(contact* pa);
//销毁通讯录
void Destroycontact(contact* pa);
1.1定义联系人信息
这里就要用到结构体了,结构体不熟的要去补补喽。
为了以后方便改数值,我们可以用#define全局变量声明一下。
代码如下:
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
typedef struct peoinfo
{
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tele[TELE_MAX];
char addr[ADDR_MAX];
} peoinfo;
1.2定义通讯录的内容
代码如下:
#define MAX 1000
typedef struct contact
{
peoinfo data[MAX];//通讯录容量
int sz;//记录通讯录中已经存放的信息个数
} contact;
首先我们要设计一个目录,目录的话很简单,可以根据自己喜欢设计,这里就不多说,代码如下:
void menu()
{
printf("****************************\n");
printf("**** 1.增加 2.删除 ****\n");
printf("**** 3.查找 4.修改 ****\n");
printf("**** 5.排序 6.打印 ****\n");
printf("**** 0.退出 ****\n");
printf("****************************\n");
}
运行结果如下:
设计完目录后,我们还要把我们的主函数设计出来
代码如下:
void test()
{
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 SEARCH:
Searchcontact(&con);
break;
case MODIFY:
Modifycontact(&con);
break;
case SORT:
Sortcontact(&con);
break;
case PRINT:
Printcontact(&con);
break;
case EXIT:
Savecontact(&con);
Destroycontact(&con);
printf("退出通讯录\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
对于这些功能我们可以用枚举来达到这样的效果
代码如下:
//枚举
enum Option
{
EXIT,//退出
ADD,//增加
DEL,//删除
SEARCH,//查找
MODIFY,//修改
SORT,//排序
PRINT//打印
};
最开始我们的通讯录是一个人也没有,所以我们要把通讯录的内容全都初始化为0,否则是随机值,那我们后面在进行下去也是毫无意义的。
代码如下:
void Initcontact(contact* pa)
{
pa->sz = 0;//设置通讯录只有0个元素
memset(pa->data, 0, sizeof(pa->data));//初始化数组
}
这个是最简单的,有手就行,不多讲。
代码如下:
void Printcontact(contact* pa)
{
assert(pa);
int i = 0;
printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
for (i = 0; i < pa->sz; i++)
{
printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[i].name,pa->data[i].age,pa->data[i].sex,pa->data[i].tele,pa->data[i].addr);
}
}
这里我们一定要注意断言哦!!!
这里的判断语句也是需要用动态版本进一步升级的地方。
void Addcontact(contact* pa)
{
assert(pa);
if (pa->sz == MAX)
{
printf("通讯录已满,无法添加\n");
}
//录入信息
printf("请输入名字:>");
scanf("%s", pa->data[pa->sz].name);
printf("请输入年龄:>");
scanf("%d", &pa->data[pa->sz].age);
printf("请输入性别:>");
scanf("%s", pa->data[pa->sz].sex);
printf("请输入电话:>");
scanf("%s", pa->data[pa->sz].tele);
printf("请输入地址:>");
scanf("%s", pa->data[pa->sz].addr);
pa->sz++;
printf("添加成功\n");
}
演示结果:
7、 删除联系人
删除联系人分两步,一是先要找到改联系人,二再是删除,还要注意判断一下通讯录是否为空。
代码如下:
//找到了返回下标
//找不到返回-1
int FindName(const contact* pa, char name[])
{
assert(pa);
int i = 0;
for (i = 0; i < pa->sz; i++)
{
if (0 == strcmp(pa->data[i].name, name))
{
return i;
}
}
return -1;
}
这里用了一个FindName函数在后面的查找联系人中也用的到。
void Delcontact(contact* pa)
{
assert(pa);
if (pa->sz==0)
{
printf("通讯录已空\n");
}
//1、找到
char name[NAME_MAX] = { 0 };
printf("请输入要删除的名字:>");
scanf("%s", name);
int pos = FindName(pa, name);
if (pos == -1)
{
printf("要删除的人不存在\n");
return;
}
//2、删除
int j = 0;
for (j = pos; j < pa->sz - 1; j++)
{
pa->data[j] = pa->data[j + 1];
}
pa->sz--;
printf("删除成功\n");
}
演示效果:
查找联系人我并不需要修改它,所以我们可以用const限定一下。
代码如下:
void Searchcontact(const contact* pa)
{
char name[NAME_MAX] = { 0 };
printf("请输入要查找的名字:>");
scanf("%s", name);
int pos = FindName(pa, name);
if (pos == -1)
{
printf("要查找的人不存在\n");
return;
}
printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);
}
演示效果:
这里我用的是qsort函数更简单一点,不过要注意qsort函数的参数不要用错了,当然你们也可以用别的,比如冒泡排序也是可行的。
代码如下:
int Cmpname(const void* e1, const void* e2)
{
return strcmp(((peoinfo*)e1)->name,((peoinfo*)e2)->name);
}
void Sortcontact(contact* pa)
{
assert(pa);
qsort(pa->data, pa->sz, sizeof(pa->data[0]), Cmpname);
printf("排序成功\n");
}
演示效果:
#include
#include
#include
#include
contact.h
#pragma once
#include
#include
#include
#include
//类型声明
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 1000
//通讯录初始状态的容量大小
#define DEFAULT_SZ 5
//枚举
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT
};
typedef struct peoinfo
{
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tele[TELE_MAX];
char addr[ADDR_MAX];
} peoinfo;
//静态的版本
//typedef struct contact
//{
// peoinfo data[MAX];//通讯录容量
// int sz;//记录通讯录中已经存放的信息个数
//} contact;
//动态的版本
typedef struct contact
{
peoinfo* data;//可以存放1000个人的信息
int sz;//记录通讯中已经保存的信息个数
int capacity;//记录通讯录当前的最大容量
} contact;
//函数声明
//初始化通讯录
void Initcontact(contact* pa);
//增加联系人的信息
void Addcontact(contact* pa);
//删除指定联系人的信息
void Delcontact(contact* pa);
//打印通讯录中的信息
void Printcontact(contact* pa);
//查找指定联系人信息
void Searchcontact(const contact* pa);
//按字典顺序排序
void Sortcontact(contact* pa);
//修改指定联系人的信息
void Modifycontact(contact* pa);
//销毁通讯录
void Destroycontact(contact* pa);
//文件版本
void Savecontact(const contact* pa);
contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
//静态的版本
//void Initcontact(contact* pa)
//{
// pa->sz = 0;
// memset(pa->data, 0, sizeof(pa->data));//初始化数组
//}
//动态的版本
//void Initcontact(contact* pa)
//{
// assert(pa);
// pa->sz = 0;
// pa->capacity = DEFAULT_SZ;
// pa->data = (peoinfo*)malloc(pa->capacity * sizeof(peoinfo));
// if (pa->data == NULL)
// {
// perror("Initcontact::malloc");
// return;
// }
// memset(pa->data, 0, pa->capacity * sizeof(peoinfo));//初始化数组
//}
void checkcapacity(contact* pa)//检查容量
{
if (pa->sz == pa->capacity)
{
peoinfo* tmp = (peoinfo*)realloc(pa->data, (pa->capacity + 3) * sizeof(peoinfo));
if (tmp != NULL)
{
pa->data = tmp;
}
else
{
perror("checkcapacity::realloc");
return;
}
pa->capacity += 3;
printf("增容成功\n");
}
}
void Loadcontact(contact* pa)
{
//打开文件
FILE* pf = fopen("contact.txt", "rb");
if (pf == NULL)
{
perror("Loadconatct::fopen");
return;
}
//读文件
peoinfo tmp = { 0 };
while (fread(&tmp, sizeof(peoinfo), 1, pf))
{
checkcapacity(pa);
pa->data[pa->sz] = tmp;
pa->sz++;
}
//关闭文件
fclose(pf);
pf = NULL;
}
//文件版本
void Initcontact(contact* pa)
{
assert(pa);
pa->sz = 0;
pa->capacity = DEFAULT_SZ;
pa->data = (peoinfo*)malloc(pa->capacity * sizeof(peoinfo));
if (pa->data == NULL)
{
perror("Initcontact::malloc");
return;
}
memset(pa->data, 0, pa->capacity * sizeof(peoinfo));//初始化数组
//加载文件信息到通讯录中
Loadcontact(pa);
}
void Addcontact(contact* pa)
{
assert(pa);
//静态的版本
/*if (pa->sz == MAX)
{
printf("通讯录已满,无法添加\n");
}*/
//录入信息
//动态的版本
checkcapacity(pa);
printf("请输入名字:>");
scanf("%s", pa->data[pa->sz].name);
printf("请输入年龄:>");
scanf("%d", &pa->data[pa->sz].age);
printf("请输入性别:>");
scanf("%s", pa->data[pa->sz].sex);
printf("请输入电话:>");
scanf("%s", pa->data[pa->sz].tele);
printf("请输入地址:>");
scanf("%s", pa->data[pa->sz].addr);
pa->sz++;
printf("添加成功\n");
}
//找到了返回下标
//找不到返回-1
int FindName(const contact* pa, char name[])
{
assert(pa);
int i = 0;
for (i = 0; i < pa->sz; i++)
{
if (0 == strcmp(pa->data[i].name, name))
{
return i;
}
}
return -1;
}
void Delcontact(contact* pa)
{
assert(pa);
if (pa->sz==0)
{
printf("通讯录已空\n");
}
//1、找到
char name[NAME_MAX] = { 0 };
printf("请输入要删除的名字:>");
scanf("%s", name);
int pos = FindName(pa, name);
if (pos == -1)
{
printf("要删除的人不存在\n");
return;
}
//2、删除
int j = 0;
for (j = pos; j < pa->sz - 1; j++)
{
pa->data[j] = pa->data[j + 1];
}
pa->sz--;
printf("删除成功\n");
}
void Printcontact(contact* pa)
{
assert(pa);
int i = 0;
printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
for (i = 0; i < pa->sz; i++)
{
printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[i].name,pa->data[i].age,pa->data[i].sex,pa->data[i].tele,pa->data[i].addr);
}
}
void Searchcontact(const contact* pa)
{
char name[NAME_MAX] = { 0 };
printf("请输入要查找的名字:>");
scanf("%s", name);
int pos = FindName(pa, name);
if (pos == -1)
{
printf("要查找的人不存在\n");
return;
}
printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);
}
int Cmpname(const void* e1, const void* e2)
{
return strcmp(((peoinfo*)e1)->name,((peoinfo*)e2)->name);
}
void Sortcontact(contact* pa)
{
assert(pa);
qsort(pa->data, pa->sz, sizeof(pa->data[0]), Cmpname);
printf("排序成功\n");
}
void Modifycontact(contact* pa)
{
char name[NAME_MAX] = { 0 };
printf("请输入要修改人的名字:>");
scanf("%s", name);
int pos = FindName(pa, name);
if (pos == -1)
{
printf("要修改的人不存在\n");
return;
}
else
{
printf("请输入修改后的名字:>");
scanf("%s", pa->data[pos].name);
printf("请输入修改后的年龄:>");
scanf("%d", &(pa->data[pos].age));
printf("请输入修改后的性别:>");
scanf("%s", pa->data[pos].sex);
printf("请输入修改后的电话:>");
scanf("%s", pa->data[pos].tele);
printf("请输入修改后的地址:>");
scanf("%s", pa->data[pos].addr);
printf("修改成功!!!\n");
}
printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);
}
void Destroycontact(contact* pa)
{
free(pa->data);
pa->data = NULL;
pa->capacity = 0;
pa->sz = 0;
printf("销毁成功\n");
}
//文件版本
void Savecontact(const contact* pa)
{
//打开文件
FILE* pf = fopen("contact.txt", "wb");
if (pf == NULL)
{
perror("Savecontact::fopen");
return;
}
//写文件
int i = 0;
for (i = 0; i < pa->sz; i++)
{
fwrite(pa->data + i, sizeof(peoinfo), 1, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{
printf("****************************\n");
printf("**** 1.增加 2.删除 ****\n");
printf("**** 3.查找 4.修改 ****\n");
printf("**** 5.排序 6.打印 ****\n");
printf("**** 0.退出 ****\n");
printf("****************************\n");
}
void test()
{
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 SEARCH:
Searchcontact(&con);
break;
case MODIFY:
Modifycontact(&con);
break;
case SORT:
Sortcontact(&con);
break;
case PRINT:
Printcontact(&con);
break;
case EXIT:
Savecontact(&con);
Destroycontact(&con);
printf("退出通讯录\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}