在上一篇文章中我们详细讲解了自定义类型,这篇文章我们就使用结构体实现一个简单的通讯录。
数据的存储
通讯录要存储每个联系人的信息,每个联系人的信息又由姓名,年龄,性别,电话,地址这五个因素组成,所以我们首先要创建一个结构体类型来保存每个联系人的信息。我们在头文件中声明一个People的结构体。这样一个人的信息存储方式就有了,然后我们还需要创建一个结构体来存储我们的通讯录,通讯录首先要有一个数组,整个数组的每个成员都是People的,然后我们还需要一个count变量来记录联系人的总数,因为后续我们要显示结构体和排序结构体都要用到联系人数量。所以我们再声明一个结构体类型Contact,这个结构体有两个成员,一个结构体数组,长度为100,我们用#define来定义一个MAX表示联系人的最大数量,也就是我们的结构体的数组的大小,方便后续修改结构体数组大小,另一个成员变量是count用来记录联系人数量。
#pragma once
#include<stdio.h>
#include<assert.h>
#define MAX 100
typedef struct People
{
char name[20];
int age;
char sex[5];
char tele[15];
char address[20];
}People;
typedef struct Contact
{
People data[MAX];
size_t count;
}Contact;
菜单以及通讯录初始化
我们需要一个菜单来让用户选择要进行的操作,增删查改排序显示和退出,我们都要在菜单中显示出来,在用户进行操作之前,我们还要对体现了进行初始化,否则通讯录里面都是一些随机值,将count初始化为0;
#include"contact.h"
void Menu()
{
printf("*******************************\n");
printf("***** 1.Add 2.Delete *****\n");
printf("***** 3.Search 4.Modify *****\n");
printf("***** 5.Sort 6.Show *****\n");
printf("******0.Exit *****\n");
printf("*******************************\n");
}
void Init_Contact(Contact* pc)
{
int i = 0;
for (i = 0; i < MAX; i++)
{
*((pc->data[i]).name) = 0;
(pc->data[i]).age = 0;
*((pc->data[i]).sex) = 0;
*((pc->data[i]).tele) = 0;
*((pc->data[i]).address) = 0;
}
pc->count = 0;
}
int main()
{
int input = 0;
Contact contact;
Init_Contact(&contact);
do
{
Menu();
printf("请选择_>");
scanf("%d", &input);
switch (input)
{
case 1:
//增加联系人
break;
case 2:
//删除联系人
break;
case 3:
//查找联系人
break;
case 4:
//修改联系人
break;
case 5:
//排序联系人
break;
case 6:
//显示联系人
break;
case 0:
//退出
printf("退出通讯录\n");
break;
default:
printf("选择错误,请重新选择:\n");
break;
}
} while (input);
return 0;
}
增加联系人
当用户选择增加联系人时,我们需要调用Add_Contact函数,在这个函数中,首先需要用户输入联系人的五项信息,如果增加成功,打印提示信息,如果容量满了,打印提示信息。
void Add_Contact(Contact* pc)
{
assert(pc);
if (pc->count <= MAX)
{
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);
(pc->count)++;
printf("增加完成\n");
}
else
{
printf("联系人已满,请删除一些联系人\n");
}
}
显示联系人
因为我们后面的的代码的测试都要显示联系人列表来观察,所以我们把这个函数实现在前面以便于我们测试程序是否正常运行。
显示联系人只需要我们循环打印count个联系人的信息出来就行了。
void Show_Contact(Contact* pc)
{
assert(pc);
int i = 0;
printf("姓名 年龄 性别 电话 地址\n");
for (i = 0; i < pc->count; i++)
{
printf("%-15s %-5d %-5s %-15s %-20s\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].address);
}
}
查找联系人
因为在删除和修改联系人时我们也要用到查找联系人这个函数,所以我们先实现查找联系人。
查找联系人函数的设计我们采用按名字查找,然后遍历整个联系人列表,通过strcmp函数的返回值来判断是否是所查找的联系人,我们在这个函数可以给一个返回值,用于删除函数的使用,我们可以要查找返回联系人的下标。
//具体查找的函数
int Find_By_Name(Contact* pc, char* findname)
{
assert(pc);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (strcmp(pc->data[i].name
, findname) == 0)
{
//找到就直接返回
return i;
}
}
//遍历完了没有返回则说明找不到
return -1;//返回-1表示找不到
}
//查找功能的函数
void Search_Contact(Contact* pc)
{
assert(pc);
int i = 0;
printf("请输入要查找的联系人姓名:");
char search_name[20] = { 0 };
scanf("%s", search_name);
int ret = Find_By_Name(pc, search_name);
if (ret == -1)
{
printf("找不到该联系人\n");
}
else
{
printf("%-15s %-5d %-5s %-15s %-20s\n",
pc->data[ret].name,
pc->data[ret].age,
pc->data[ret].sex,
pc->data[ret].tele,
pc->data[ret].address);
}
}
删除联系人
删除联系人的函数逻辑也十分简单,首先要通过前面的查找函数来找到要删除联系人的下标,然后从这个下标开始,后面的数据往前面覆盖,最末尾的一个数据我们可以删也可以不删,因为我们会让count-1,所以最末尾的那个数据无所谓。
void Delete_Contact(Contact* pc)
{
assert(pc);
char delete_name[20] = { 0 };
printf("请输入要删除的联系人姓名:");
scanf("%s", delete_name);
int ret = Find_By_Name(pc,delete_name);
if (ret == -1)
{
printf("找不到要删除的联系人\n");
}
else
{
int i = 0;
for (i = ret; i < pc->count - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->count--;
printf("删除成功\n");
}
}
修改联系人
修改联系人的逻辑和删除联系人相同,先找到下标,再进行修改,修改就是让用户重新输入一个信息。
//修改联系人
void Modify_Contact(Contact* pc)
{
assert(pc);
if (pc->count == 0)
{
printf("当前无联系人\n");
return;
}
char modify_name[20] = { 0 };
printf("请输入要修改的联系人名字;");
scanf("%s", modify_name);
int ret = Find_By_Name(pc, modify_name);
if (ret == -1)
{
printf("找不到该联系人\n");
}
else
{
printf("请重新输入修改后的联系人信息\n");
printf("请输入姓名:");
scanf("%s", pc->data[ret].name);
printf("请输入年龄:");
scanf("%d", &(pc->data[ret].age));
printf("请输入性别:");
scanf("%s", pc->data[ret].sex);
printf("请输入电话:");
scanf("%s", pc->data[ret].tele);
printf("请输入地址:");
scanf("%s", pc->data[ret].address);
printf("修改完成\n");
}
}
排序联系人
排序联系人这个函数我们可以用库里面的qsort函数来实现。
//qsort的比较函数,按名字排序
int cmp_by_name(const void* a, const void* b)
{
assert(a && b);
return strcmp( ((People*)a)->name, ((People*)b)->name);
}
//排序联系人
void Sort_Contact(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->count, sizeof(People), cmp_by_name);
printf("排序成功\n");
}
这样一个简单的通讯录就实现了,目前我们的通讯录联系人数量是固定的,而且每次退出程序后联系人的信息就销毁了,说明我们的通讯录还不是最终版本,后续更新完动态内存分配和文件操作后还会有两个升级的版本。
标签:name,--,联系人,pc,Contact,通讯录,应用,printf,data From: https://blog.csdn.net/weixin_64099089/article/details/137081184