前言
我们通过对结构体的学习,我们可以写一个能存放 100 个人信息的通讯录,来对结构体的相关知识进行练习。
通讯录要求
通讯录要包含 菜单、增加联系人、删除联系人、查找联系人、修改联系人、展示所有联系人、排序联系人。
联系人的信息:
姓名,性别,年龄,电话,地址。
/*注:我们在删除、查找、修改时,为了简化,我们可以只通过姓名来删除、查找和修改,排序时我们可以只写按照姓名排序的方案。
文件的构成
头文件:phone_book.h
源文件:phone_book.c
text.c
头文件 主要存放的是 宏定义的一些值,库函数的引用,函数的声明 等。
源文件:phone_book. 主要存放 函数的实现;
text.c 主要是程序实现的过程。
过程
常量的定义
//常量的宏定义
#define max_data 100
#define max_name 20
#define max_sex 5
#define max_tele 15
#define max_addr 30
这里我们定义了 数据的大小、名字的大小、性别的大小、电话的大小、地址的大小
我们把它放在 phone_book.h 中。
/*注:我们在程序中对一些常量的使用,最好把常量进行 宏定义,这样方便我们后期的修改与维护。
结构体联系人相关信息的创建
//结构体联系人相关信息的创建
struct contact
{
char name[max_name];
char sex[5];
int age;
char tele[15];
char addr[max_addr];
};
我们创建了联系人的相关信息的结构体。
我们把它放在 phone_book.h 中。
通讯录结构体的创建
//通讯录的创建
struct phone_book
{
struct contact data[max_data];
int sz;
};
我们把它放在 phone_book.h 中。
接下来我们就可以进行主函数的创建了。
主函数的创建
#define _CRT_SECURE_NO_WARNINGS 1
#include "phone_book.h"
//通讯录功能的菜单
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");
}
enum fun
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
//主函数的创建
int main()
{
int input = 0;
//创建通讯录
struct phone_book pc;
//初始化通讯录
initphone_book(&pc);
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
{
add_contact(&pc);
break;
}
case DEL:
{
del_contact(&pc);
break;
}
case SEARCH:
{
search_contact(&pc);
break;
}
case MODIFY:
{
modify_contact(&pc);
break;
}
case SHOW:
{
show_contact(&pc);
break;
}
case SORT:
{
sort_contact(&pc);
break;
}
case EXIT:
{
printf("已退出!\n");
break;
}
default:
{
printf("选择错误,请重新输入:");
break;
}
}
system("pause");
system("cls");
}while (input);
return 0;
}
这里我们创建了 菜单 、枚举 、还有 主函数。
菜单为了用户更加方便的打印;
枚举是为了避免我们在编写时,switch语句中频繁使用没有意义的数字,而导致代码难以理解的问题;
同时我们有增加了 暂停 和 清屏的相关功能。
这些代码我们把它放在 text.c 中。
接下我们只需进行函数的实现即可,完成工作。
函数的实现
#define _CRT_SECURE_NO_WARNINGS 1
#include "phone_book.h"
//通讯录的初始化
void initphone_book(struct phone_book* pc)
{
memset(pc->data, 0, max_data * sizeof(struct contact));
pc->sz = 0;
}
//增加联系人
void add_contact(struct phone_book* pc)
{
if (pc->sz == max_data)
{
printf("所创建空间不足!\n");
return;
}
printf("请输入联系人姓名:");
scanf("%s", pc->data[pc->sz].name);
printf("请输入联系人性别:");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入联系人年龄:");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入联系人电话:");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入联系人地址:");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("添加成功!\n");
}
//展示联系人
void show_contact(struct phone_book* pc)
{
int i = 0;
printf("%-20s\t%-5s\t%-3s\t%-15s\t%-30s\n",
"名字", "性别", "年龄", "电话", "地址");
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t", pc->data[i].name);
printf("%-5s\t", pc->data[i].sex);
printf("%-3d\t", pc->data[i].age);
printf("%-15s\t", pc->data[i].tele);
printf("%-30s", pc->data[i].addr);
printf("\n");
}
}
//由名字查找联系人,返回其数据的下标
int find_one(struct phone_book* pc, char* name1)
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name1) == 0)
return i;
}
return -1;
}
//展示一个联系人的信息
void show_one(struct phone_book* pc, int i)
{
printf("%-20s\t%-5s\t%-3s\t%-15s\t%-30s\n",
"名字", "性别", "年龄", "电话", "地址");
printf("%-20s\t", pc->data[i].name);
printf("%-5s\t", pc->data[i].sex);
printf("%-3d\t", pc->data[i].age);
printf("%-15s\t", pc->data[i].tele);
printf("%-30s", pc->data[i].addr);
printf("\n");
}
//删除联系人
void del_contact(struct phone_book* pc)
{
char name1[max_name];
int ret = 0;
printf("请输入所需删除联系人的姓名:");
scanf("%s", name1);
ret = find_one(pc, name1);
if (ret == -1)
{
printf("联系人不存在!\n");
return;
}
show_one(pc, ret);
memmove(pc->data + ret, pc->data + ret + 1, (pc->sz - 1 - ret) * sizeof(struct contact));
memset(pc->data + pc->sz - 1, 0, sizeof(struct contact));
pc->sz--;
printf("已删除联系人!\n");
}
//查找联系人
void search_contact(struct phone_book* pc)
{
char name1[max_name];
int ret = 0;
printf("请输入所需查找联系人姓名:");
scanf("%s", name1);
ret = find_one(pc, name1);
if(ret == -1)
{
printf("联系人不存在!\n");
return;
}
show_one(pc, ret);
}
//修改联系人
void modify_contact(struct phone_book* pc)
{
char name1[max_name];
int ret = 0;
printf("请输入所需修改联系人姓名:");
scanf("%s", name1);
ret = find_one(pc, name1);
if (ret == -1)
{
printf("联系人不存在!\n");
return;
}
show_one(pc, ret);
printf("请修改:\n");
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");
}
int name_cmp(void* e1, void* e2)
{
return strcmp(((struct contact*)e1)->name, ((struct contact*)e2)->name);
}
//排序联系人
void sort_contact(struct phone_book* pc)
{
qsort(pc->data, pc->sz, sizeof(struct contact), name_cmp);
show_contact(pc);
}
这是相关功能实现的代码。
我们把相关的功能以函数的形式实现,有助于后期的维护。
在写代码时,我们可以先写 add_contact 和 show_contact, 这样在实现其他功能时,我们能轻易的看到效果。