在对结构体和指针有一定的基础上,我们就可以来尝试着写一写这个静态版的通讯录啦~
首先,这个通讯录我们设定可以存放50个人的信息,每个人存放的信息有:姓名,年龄,性别,联系方式,地址。
我们的通讯录上的功能包含了增加联系人,删除联系人,查找和更改联系人,我们在编写程序的时候还应该在加上显示和排序这些功能。
让我们再整合一下
静态版通讯录功能:
存放50个人的信息
存放的信息有:姓名,年龄,性别,联系方式,地址
增加联系人
删除联系人
查找联系人
更改联系人信息
显示联系人信息
排序通讯录(按照名字排序)
那么就让我们一一来实现吧~~
由于代码量比较大,所以我们创建3个文件,一个为测试文件test.c,编写运行代码。一个为函数实现的文件contact.c,编写各种函数的实现。一个为头文件contact.h,用来声明函数。
test.c——编写运行代码
contact.c——编写实现各函数
contact.h——声明各函数
接下来进入正文~
与我之前写的文章“简单猜数字游戏的实现”(http://t.csdn.cn/cHL3X)的菜单部分一样,用do-while语句来实现,并输入选项。
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;
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:
break;
default:
break;
}
} while (input);
return 0;
}
这里我们可以使用枚举常量来代替这些数字,这样如果在功能比较多的情况下就不需要返回去看数字所对应的功能是什么
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
int main()
{
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
break;
case DEL:
break;
case SEARCH:
break;
case MODIFY:
break;
case SHOW:
break;
case SORT:
break;
case EXIT:
break;
default:
break;
}
} while (input);
完成基础的菜单部分后,现在开始实现功能的完成。
我们需要在头文件中声明该功能函数
首先我们先构建一个结构体来储存一个人的信息,再用另一个结构体储存整个通讯录的信息
其中使用宏定量定义,是为了以后更方便更改数值
Contact中的data是储存每个联系人的信息,而sz是统计联系人个数。
首先初始化通讯录(注意,要先在头文件中声明)
然后在contact.c文件中实现
注意:在传参和接收的都应该是地址和指针,应该我们需要改变实参的值,所以需要传输地址才能实现
每写完一个功能我们便应该测试是否有问题
分别是初始化前与初始化后的图片,可以看到,初始化成功,那么我们就可以进入下一步
//增加联系人
void AddContact(Contact* pc)
{
if (pc->sz >= MAX)
{
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].tele);
printf("请输入地址:");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
return;
}
首先我们需要判断通讯录是否已满,如果满了则提示,并返回,否则输入需要储存的信息
为了方便测试,我们先写一个显示通讯录的函数
//显示通讯录
void ShowContact(Contact* pc)
{
int i = 0;
printf("%-15s %-5s %-5s %-15s %-30s\n", "姓名", "年龄", "性别", "联系方式", "地址");
for (i = 0; i < pc->sz; i++)
{
printf("%-15s %-5d %-5s %-15s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
}
}
为了便于观看及美观,在每个项目之间设置一定的间隔
“%-15s %-5s %-5s %-15s %-30s”
“-”号是表示左对齐,不加则表示右对齐
出现的是这样的,我们在前面写了增加联系人的函数,我们输入信息后会是怎么样的,我们来试试
也是很顺利的显示了出来
//删除联系人
void DelContact(Contact* pc)
{
char name[MAX_NAME] = { 0 };
int i = 0;
int pos = 0;
if (pc->sz == 0)
{
printf("通讯录为空\n");
return;
}
printf("请输入需要删除的人的姓名:");
scanf("%s", name);
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(name, pc->data[i].name))
{
pos = i;
break;
}
}
if (i == pc->sz)
{
printf("无该联系人\n");
return;
}
for (i = pos; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
printf("删除成功\n");
pc->sz--;
return;
}
我先添加三组数据
也是没有问题的
接下来的功能我就不一一测试了
//查找联系人
void SearchContact(Contact* pc)
{
char name[MAX_NAME] = { 0 };
int i = 0;
int pos = 0;
printf("请输入需要查找联系人的姓名:");
scanf("%s", name);
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(name, pc->data[i].name))
{
pos = i;
break;
}
}
if (i == pc->sz)
{
printf("无该联系人\n");
return;
}
printf("%-15s %-5s %-5s %-15s %-30s\n", "姓名", "年龄", "性别", "联系方式", "地址");
printf("%-15s %-5d %-5s %-15s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
}
我们发现在查找联系人的时候有部分是和删除联系人的部分是相同的,所以我们可以将相同的部分分装起来,变成独立的一个函数FindContact,然后简化该函数
int FindContact(const Contact* pc,const char* name)
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(name, pc->data[i].name))
{
return i;
}
}
return -1;
}
所以新的DelContact与SearchContact函数转化为
//删除联系人
void DelContact(Contact* pc)
{
char name[MAX_NAME] = { 0 };
int i = 0;
int pos = 0;
if (pc->sz == 0)
{
printf("通讯录为空\n");
return;
}
printf("请输入需要删除的人的姓名:");
scanf("%s", name);
pos = FindContact(pc, name);
if (pos == -1)
{
printf("无该联系人\n");
return;
}
for (i = pos; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
printf("删除成功\n");
pc->sz--;
return;
}
//查找联系人
void SearchContact(Contact* pc)
{
char name[MAX_NAME] = { 0 };
int i = 0;
printf("请输入需要查找联系人的姓名:");
scanf("%s", name);
i = FindContact(pc, name);
if (i == -1)
{
printf("无该联系人\n");
return;
}
printf("%-15s %-5s %-5s %-15s %-30s\n", "姓名", "年龄", "性别", "联系方式", "地址");
printf("%-15s %-5d %-5s %-15s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
}
//更改联系人
void ModifyContact(Contact* pc)
{
char name[MAX_NAME] = { 0 };
int i = 0;
printf("请输入需要更改联系人的姓名:");
scanf("%s", name);
i = FindContact(pc, name);
if (-1 == i)
{
printf("无该联系人\n");
return;
}
printf("请输入新的姓名:");
scanf("%s", pc->data[i].name);
printf("请输入年龄:");
scanf("%d", &(pc->data[i].age));
printf("请输入性别:");
scanf("%s", pc->data[i].sex);
printf("请输入联系方式:");
scanf("%s", pc->data[i].tele);
printf("请输入地址:");
scanf("%s", pc->data[i].addr);
printf("更改成功\n");
return;
}
其中,又要查找联系人,所以我们可以直接用之前所分装的函数来解决
//排序联系人
int cmp_by_name(const void* e1, const void* e2)
{
return(strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name));
}
void SortContact(Contact* pc)
{
qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);
printf("排序成功\n");
}
这里我们可以直接用快速排序的方法来对我们的通讯录进行排序,如果不了解快速排序可以去看看关于快速排序相关的文章,这里我就不详细展开啦
好啦,静态版通讯录就到这里啦~~
还有什么不懂的可以来找博主哦~~
喜欢的话记得三连哦~~~
感谢支持!!!