前言
使用C语言模拟一个通讯录,通讯录最大可以存储1000个人的信息。
存储的信息包括:姓名、性别、年龄、电话号码、地址
能实现的功能包括:1。新增联系人;2.删除联系人;3.查找联系人:根据姓名查找;4.修改联系人;5.排序联系人:将通讯录中的联系人根据姓名首字母的大小升序排列、6.打印通讯录中的联系人的所有信息、7.退出通讯录
一、通讯录菜单
设计一个菜单,向用户展示功能,用来和用户交互
void menu()
{
printf("******************************\n");
printf("**** 1.add 2.del *****\n");
printf("**** 3.search 4.modify *****\n");
printf("**** 5.sort 6.print *****\n");
printf("**** 0.exit *****\n");
printf("******************************\n");
}
打印出来的效果
二、通讯录主函数
函数主体使用do……while循环对输入的选项进行判断,当输入为0时跳出循环,程序结束。不为0时,用switch语句跳转到相对应的功能,代码如下:
void test()
{
int input = 0;
Contacts con;//创建通讯录
do
{
menu();
printf("请选择功能:>");
scanf("%d", &input);
switch (input)
{
case ADD:
break;
case DEL:
break;
case SEARCH:
break;
case MODIFY:
break;
case SORT:
break;
case PRINT:
break;
case EXIT:
break;
default:
printf("选项不存在,请重新选择\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
三、枚举通讯录选项
switch语句会根据输入值,跳入不同的case语句中。上面代码为了可读性将case后面的数值替换成了对应的选项,无法达到switch的效果,因此使用枚举对选项赋值。
//枚举所有的选项数据
enum Option
{
EXIT,//默认为0
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT
};
四、定义通讯录和联系人
1.定义联系人的信息(结构体)
联系人的信息不是单一类型,使用结构体创建一个联系人类型
//一个联系人的身份信息数据
typedef struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
int age;
}PeoInfo;
2.定义通讯录信息(结构体)
通讯录里面既要有联系人的身份信息,也要能让人知道保存联系人的个数。这里我们创建一个上述联系人的结构体类型的数组,用来保存联系人的身份信息
//通讯录的信息数据
typedef struct Contacts
{
int count;//通讯录中联系人的总数
PeoInfo data[MAX_CONTACTS];//通讯录中所有人的信息
}Contacts;
五、全局变量声明
为了方便日后对通讯录的修改和完善,将所有需要指定数组元素个数的数据进行声明
//定义的类型
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 20
#define MAX_CONTACTS 1000
六、通过姓名查找联系人的函数
//查找联系人的姓名,找到了返回下标,找不到返回-1
static int FindByName(Contacts* pc, char* pch)
{
assert(pc && pch);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (strcmp(pc->data[i].name, pch) == 0)
{
return i;
}
}
return -1;
}
七、实现通讯录功能的函数
1.初始化通讯录
开始将通讯录中的人数初始化为0;将通讯录中的联系人信息数组初始化为0
void IntContacts(Contacts* pc)
{
assert(pc);
pc->count = 0;
memset(pc->data, 0, sizeof(pc->data));//初始化的地址为结构体中的data数组的地址,初始化的值为0,初始化的长度为数组的长度
}
2.新增联系人
当通讯录中没有人的时候,count的值为0,数组的下标也是0,新增的信息要放在数组下标为0处;当通讯录中有1个人时,count为1时,新增的信息要放在数组的下标为1处。按此规律count的值正好等于等于要新增的信息所存放的数组的下标
//新增联系人
void AddContacts(Contacts* pc)
{
assert(pc);
if (pc->count < MAX_CONTACTS)
{
printf("请输入姓名:>");
scanf("%s", pc->data[pc->count].name);
printf("请输入性别:>");
scanf("%s", pc->data[pc->count].sex);
printf("请输入年龄:>");
scanf("%d", &pc->data[pc->count].age);
printf("请输入电话:>");
scanf("%s", pc->data[pc->count].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pc->count].addr);
pc->count++;
printf("添加成功\n");
}
else
{
printf("通讯录已满,无法新增\n");
}
}
3.删除联系人
封装一个函数FindByName,通过输入名字查找要删除的联系人
//删除联系人
void DelContacts(Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
char ch[MAX_NAME] = { 0 };
printf("请输入要删除联系人的姓名\n");
scanf("%s", ch);
int ret = FindByName(pc, ch);
if (ret != -1)
{
int i = 0;
for (i = ret; i < pc->count; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->count--;
printf("已删除\n");
}
else
{
printf("该联系人不存在\n");
}
}
4.查找联系人
//查找联系人
void SearchContacts(const Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
char ch[MAX_NAME] = { 0 };
printf("请输入要查找的联系人的姓名\n");
scanf("%s", ch);
int ret = FindByName(pc, ch);
if (ret != -1)
{
printf("%-20s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s %-5s %-5d %-12s %-20s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr);
}
else
{
printf("该联系人不存在\n");
}
}
5.修改联系人
//修改联系人
void ModifyContact(Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
char ch[MAX_NAME] = { 0 };
printf("请输入要修改联系人的姓名\n");
scanf("%s", ch);
int ret = FindByName(pc, ch);
if (ret != -1)
{
printf("%-20s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s %-5s %-5d %-12s %-20s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr);
printf("请输入修改后的姓名:>");
scanf("%s", pc->data[ret].name);
printf("请输入修改后的性别:>");
scanf("%s", pc->data[ret].sex);
printf("请输入修改后的年龄:>");
scanf("%d", &pc->data[ret].age);
printf("请输入修改后的电话:>");
scanf("%s", pc->data[ret].tele);
printf("请输入修改后的地址:>");
scanf("%s", pc->data[ret].addr);
printf("添加成功\n");
}
else
{
printf("该联系人不存在\n");
}
}
6.排序联系人
//qsort函数的判断项
static int CmpName(const void* e1, const void* e2)
{
return strcmp((PeoInfo*)e1, (PeoInfo*)e2);
}
//排序联系人
void SortContacts(Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
qsort(pc->data, pc->count, sizeof(pc->data[0]), CmpName);
printf("排序完成\n");
}
7.打印联系人
这里我用for循环
//打印联系人
void PrintContacts(const Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
printf("%-20s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
int i = 0;
for (i = 0; i < pc->count; i++)
{
printf("%-20s %-5s %-5d %-12s %-20s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr);
}
}
八、头文件
#include <stdio.h>
#include <assert.h>
#include <string.h>
九、完整代码
//contacts.h
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <string.h>
//定义的类型
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 20
#define MAX_CONTACTS 100
//一个联系人的身份信息数据
typedef struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
int age;
}PeoInfo;
//通讯录的信息数据
typedef struct Contacts
{
int count;//通讯录中联系人的总数
PeoInfo data[MAX_CONTACTS];//通讯录中所有人的信息
}Contacts;
//枚举所有的选项数据
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT
};
//定义的函数
//初始化通讯录
void IntContacts(Contacts* pc);
//新增联系人
void AddContacts(Contacts* pc);
//删除联系人
void DelContacts(Contacts* pc);
//查找联系人
void SearchContacts(const Contacts* pc);
//修改联系人
void ModifyContact(Contacts* pc);
//排序联系人
void SortContacts(Contacts* pc);
//打印联系人
void PrintContacts(const Contacts* pc);
//contacts.c
#include "contact.h"
//初始化通讯录
void IntContacts(Contacts* pc)
{
assert(pc);
pc->count = 0;
memset(pc->data, 0, sizeof(pc->data));//初始化的地址为结构体中的data数组的地址,初始化的值为0,初始化的长度为数组的长度
}
//新增联系人
void AddContacts(Contacts* pc)
{
assert(pc);
if (pc->count < MAX_CONTACTS)
{
printf("请输入姓名:>");
scanf("%s", pc->data[pc->count].name);
printf("请输入性别:>");
scanf("%s", pc->data[pc->count].sex);
printf("请输入年龄:>");
scanf("%d", &pc->data[pc->count].age);
printf("请输入电话:>");
scanf("%s", pc->data[pc->count].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pc->count].addr);
pc->count++;
printf("添加成功\n");
}
else
{
printf("通讯录已满,无法新增\n");
}
}
//查找联系人的姓名,找到了返回下标,找不到返回-1
static int FindByName(Contacts* pc, char* pch)
{
assert(pc && pch);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (strcmp(pc->data[i].name, pch) == 0)
{
return i;
}
}
return -1;
}
//删除联系人
void DelContacts(Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
char ch[MAX_NAME] = { 0 };
printf("请输入要删除联系人的姓名\n");
scanf("%s", ch);
int ret = FindByName(pc, ch);
if (ret != -1)
{
int i = 0;
for (i = ret; i < pc->count; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->count--;
printf("已删除\n");
}
else
{
printf("该联系人不存在\n");
}
}
//查找联系人
void SearchContacts(const Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
char ch[MAX_NAME] = { 0 };
printf("请输入要查找的联系人的姓名\n");
scanf("%s", ch);
int ret = FindByName(pc, ch);
if (ret != -1)
{
printf("%-20s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s %-5s %-5d %-12s %-20s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr);
}
else
{
printf("该联系人不存在\n");
}
}
//修改联系人
void ModifyContact(Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
char ch[MAX_NAME] = { 0 };
printf("请输入要修改联系人的姓名\n");
scanf("%s", ch);
int ret = FindByName(pc, ch);
if (ret != -1)
{
printf("%-20s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s %-5s %-5d %-12s %-20s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr);
printf("请输入修改后的姓名:>");
scanf("%s", pc->data[ret].name);
printf("请输入修改后的性别:>");
scanf("%s", pc->data[ret].sex);
printf("请输入修改后的年龄:>");
scanf("%d", &pc->data[ret].age);
printf("请输入修改后的电话:>");
scanf("%s", pc->data[ret].tele);
printf("请输入修改后的地址:>");
scanf("%s", pc->data[ret].addr);
printf("添加成功\n");
}
else
{
printf("该联系人不存在\n");
}
}
//排序联系人
void SortContacts(Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
int i = 0;
for (i = 0; i < pc->count - 1; i++)
{
int j = 0;
for (j = i; j < pc->count - 1; j++)
{
if (strcmp(pc->data[i].name, pc->data[i + 1].name) > 0)
{
PeoInfo tmp = pc->data[i];
pc->data[i] = pc->data[i + 1];
pc->data[i + 1] = tmp;
}
}
}
printf("排序完成\n");
}
//打印联系人
void PrintContacts(const Contacts* pc)
{
if (pc->count == 0)
{
printf("通讯录为空\n");
return;
}
assert(pc);
printf("%-20s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
int i = 0;
for (i = 0; i < pc->count; i++)
{
printf("%-20s %-5s %-5d %-12s %-20s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr);
}
}
//test.c
#include "contact.h"
void menu()
{
printf("******************************\n");
printf("**** 1.add 2.del *****\n");
printf("**** 3.search 4.modify *****\n");
printf("**** 5.sort 6.print *****\n");
printf("**** 0.exit *****\n");
printf("******************************\n");
}
void test()
{
int input = 0;
Contacts con;//创建通讯录
IntContacts(&con);//初始化通讯录
do
{
menu();
printf("请选择功能:>");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContacts(&con);//新增联系人
break;
case DEL:
DelContacts(&con);//删除联系人
break;
case SEARCH:
SearchContacts(&con);//查找联系人
break;
case MODIFY:
ModifyContact(&con);//修改联系人
break;
case SORT:
SortContacts(&con);//排序联系人
break;
case PRINT:
PrintContacts(&con);//打印联系人
break;
case EXIT:
printf("退出通讯录\n");
break;
default:
printf("选项不存在,请重新选择\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}