C语言进阶——通讯录
目录
一. 整体框架
二. 添加联系人信息
三.显示所有联系人信息
四. 删除指定联系人信息
五. 查找指定联系人信息
六. 修改指定联系人
七 . 清空所有联系人
八. 以名字排序所有联系人
学习了结构体之后,我们便可以来实现一个简易的通讯录
这个简易的通讯录,我们就简单的设置这么几个功能
添加联系人信息
删除指定联系人信息
查找指定联系人信息
修改指定联系人信息
显示所有联系人信息
清空所有联系人
以名字排序所有联系人
一. 整体框架
首先,每个人所包含的信息应该有姓名、性别、年龄、电话、住址
这需要一个结构体来存放,同时,为了将每个人的信息存储为一个整体,我们可以使用一个结构体数组,为了方便上述功能的进行,我们还可以将这个数组与数组的大小作为一个结构体
typedef struct PeoInfo
{
char name[20];
int age;
char sex[6];
char addr[20];
char tele[12];
}PeoInfo;
typedef struct Contact
{
PeoInfo data[1000];
int sz;
}Contact;
之后,我们可以先将各个功能的函数先声明出来,之后统一实现
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//显示通讯录中的信息
void ShowContact(const Contact* pc);
//查找指定联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//清空通讯录
void EmptyContact(Contact* pc);
这样,头文件中的内容就基本完成了。
之后,我们就需要在一个源文件中定义各个函数,另一个源文件中存放主函数
主函数中,主要的就是目录
void menu()
{
printf("************************************\n");
printf("****** 1. add 2. del ******\n");
printf("****** 3. search 4. modify ******\n");
printf("****** 5. show 6. empty ******\n");
printf("****** 7.sort 0. exit ******\n");
printf("************************************\n");
}
int main()
{
int input = 0;
Contact con;
InitContact(&con);
char sort[5] = "name";
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:
EmptyContact(&con);
break;
case 7:
Sort(&con);
break;
case 0:
return 0;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
二. 添加联系人信息
没什么好注意的,只需要注意的是,由于我们写的通讯录是静态的(动态的懒得写了,反正数据结构的顺序表实现过了),我们要注意是否数组存满
void AddContact(Contact* pc)
{
assert(pc);
if (pc->sz == 1000)
{
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++;
}
三.显示所有联系人信息
简单来说,就是将所有成员打印出来
而为了更加美观,我们可以指定各个元素打印的位数
void SearchContact(const Contact* pc)
{
assert(pc);
char name[20];
printf("请输入想要查找的人的名字:");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("所查找的人不存在");
return;
}
printf("%-20s%-4s%-6s%-20s%-12s", "名字", "年龄", "性别", "地址", "联系方式\n");
printf("%-20s%-4d%-6s%-20s%-12s\n",
pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].addr,
pc->data[pos].tele);
}
例如,我们这边类似于%-20s,就是将其左对齐,当然,我们也可以不加符号实现右对齐
同时,我们还在打印前表明了各个位置的含义。
四. 删除指定联系人信息
想要实现删除,我们需要先找到对应名字所在数组的下标,由于后面的查找等也需要找下标,我们可以把这个过程包装成一个函数
int FindByName(const Contact* pc, char name[])
{
assert(pc);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
找到后,我们就可以将后面的数据向前挪,若是找不到,当然就不做处理
void DelContact(Contact* pc)
{
assert(pc);
char name[20];
printf("请输入想要删除的人的名字:");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("所查找的人不存在\n");
return;
}
for (int i = pos; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
}
当然,若是通讯录本身为空,肯定是找不到下标的,也会是不做处理的情况
五. 查找指定联系人信息
与删除类似,不同的只是将删除改为打印,打印的格式也与上面的类似
void SearchContact(const Contact* pc)
{
assert(pc);
char name[20];
printf("请输入想要查找的人的名字:");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("所查找的人不存在");
return;
}
printf("%-20s%-4s%-6s%-20s%-12s", "名字", "年龄", "性别", "地址", "联系方式\n");
printf("%-20s%-4d%-6s%-20s%-12s\n",
pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].addr,
pc->data[pos].tele);
}
六. 修改指定联系人
一样的,只需要将查找到的下标位置重新输入一遍
void ModifyContact(Contact* pc)
{
assert(pc);
char name[20] = { 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");
}
七 . 清空所有联系人
直接将sz变为0即可
void EmptyContact(Contact* pc)
{
pc->sz = 0;
}
八. 以名字排序所有联系人
我们可以基于冒泡排序的思想,使用strcmp函数来完成
void Sort(Contact* pc)
{
PeoInfo temp;
for (int i = 0; i < (pc->sz) - 1; i++)
{
for (int j = 0; j < (pc->sz) - 1 - i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
temp = pc->data[j];
pc->data[j] = pc->data[j + 1];
pc->data[j + 1] = temp;
}
}
}
}
当然,各种排序方式都是可以的
同样,我们也可以将这个通讯录设置为每次插入都自动进行排序,这样的话,直接将新的数据插入即可,而同样,我们也可以选择不同的排序依据,而不只是名字,懒得写了,都差不多