设计思路讲解: 我们以手机上的通讯录为例,用C来设计一个简单的通讯录版本 通讯录的功能参照手机上的版本应该有增加,删除,修改,查找,因为我们的代码最终是在终端显示的,所以我们再给出一个显示通讯录的功能,以及最后对通讯录进行排序的功能。
我们使用结构体来集合关于通讯录中联系人的信息(定义为PeoInfo),这就需要我们要有一个关于PeoInfo的集合来存放多个人的信息,集合的大小可以由动态内存函数来开辟,内存空间不足时自动增加空间以便增添联系人。
删除时,有很多的方法,可以将要删除的联系人的信息全部改为0,然后qsort一下就ok了。也可以用该联系人后面的联系人覆盖掉要删除的,这样也能实现。方法还有很多,这里不一一给出了。
修改时我们要先输入该联系人的名字,然后重新输入信息。
查找也是要先输入联系人的名字,然后显示联系人的信息,我们发现在实现删除,修改查找等功能时,都要涉及到输入联系人的名字进行插查询,所以我们在写代码时,可以将这一功能封装成一个函数,以减少我们重复的代码。
显示通讯录就很容易实现了,只需要将所有的联系人信息全部打印出来就好了,这里可以使用循环来解决。
排序我们就使用qsort进行,可以按照名字,年龄,或者其他的信息来进行排 序,这个取决于程序员自己。
接下来我们就来开始对各个功能的代码实现,在最后会给出最后的代码。有基础的小伙伴可以直接跳到最后查看最终代码。
初始化通讯录
首先要创建一个通讯录出来才能对其初始化,前面我们说过使用PeoInfo来收集联系人的信息
struct PeoInfo { char name[MAX_NAME]; char sex[SEX]; int age; char telephone[TelePhone]; };
大小我们统一使用宏定义来操作,方便我们后续的修改。 只有一个结构体行吗?? 肯定是不行的,因为我们还需要一个集合体来存放PeoInfo的信息,所以还要有一个结构体,这个结构体包含我们的PeoInfo。
//通讯录结构体 struct Contact { //创建sz的目的是为了在进行添加删除等操作时,好找到元素的下标 int sz; struct PeoInfo* arr; int capacity;//容量大小. };
这还给出了sz和capacity两个参数,capacity是记录通讯录结构体的大小,sz是用来记录当前联系人的个数,以方便我们后续的增加,删除和查找等功能的实现,这一点如果能想到的话,后面的实现就很容易了,因为后续的大多功能都是以这两个参数为工具进行的。
结构体创建好了之后,我们就要对其初始化了,除了capacity需要给定一个初始大小之外,剩下的都要全部初始化为0。
//初始化为全0; void InitContact(struct Contact* pc) { assert(pc); pc->sz = 0; pc->capacity = 3;//默认容量大小是3 pc->arr = (struct PeoInfo*)malloc(3 * sizeof(struct PeoInfo)); if (pc->arr == NULL) { strerror(errno); return; //exit(-1) } }
我们把有关通讯录的实现的代码放到contact.c的文件中,把所有包含的头文件放在contact.h的头文件当中,把代码的主主体躯干放在test.c的测试文件当中。
相关功能的实现(增删查改显排)
剩下功能的实现以及注意事项我们在代码中注释了,大家留意一下就好,另外我把上面初始化的代码也一并在这里给大家展示出来,这里的代码就是contact.c中的代码啦~
#include "contact.h"
void InitContact(struct Contact* pc)
{
assert(pc);
pc->sz = 0;
pc->capacity = 3;
pc->arr = (struct PeoInfo*)malloc(3 * sizeof(struct PeoInfo));
if (pc->arr == NULL)
{
strerror(errno);
return;
}
}
void ADDContact(struct Contact* pc)
{
assert(pc);
if (pc->sz == pc->capacity)
{
struct PeoInfo* ptr = (struct PeoInfo*)realloc(pc->arr, (pc->capacity + 2)*sizeof(struct PeoInfo));
if (ptr == NULL)
{
strerror(errno);
return;
}
else
{
pc->capacity += 2;
pc->arr = ptr;
ptr = NULL;
printf("增容成功!\n");
}
}
printf("请输入名字:>");
scanf("%s", pc->arr[pc->sz].name);
printf("请输入性别:>");
scanf("%s", pc->arr[pc->sz].sex);
printf("请输入年龄:>");
scanf("%d", &(pc->arr[pc->sz].age));
printf("请输入电话:>");
scanf("%s", pc->arr[pc->sz].telephone);
pc->sz++;
printf("成功增加联系人\n");
}
int FindByName(const struct Contact* pc, char* n)
{
assert(pc && n);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(pc->arr[i].name, n))
{
return i;
}
}
return -1;
}
void DeleContact(struct Contact* pc)
{
assert(pc);
char n[MAX_NAME];
printf("请输入查找联系人的名字:>");
scanf("%s", n);
int ret = FindByName(pc, n);
if (ret == -1)
printf("该联系人不存在\n");
else
{
for (int j = ret; j < pc->sz - 1; j++)
{
pc->arr[j] = pc->arr[j + 1];
}
pc->sz--;
printf("成功删除指定联系人\n");
}
}
void ModifyContact(struct Contact* pc)
{
assert(pc);
printf("请输入要修改人的名字:>");
char name[MAX_NAME];
scanf("%s", name);
int ret = FindByName(pc, name);
if (ret == -1)
printf("要修改的人不存在\n");
else
{
printf("请输入名字:>");
scanf("%s", pc->arr[ret].name);
printf("请输入性别:>");
scanf("%s", pc->arr[ret].sex);
printf("请输入年龄:>");
scanf("%d", &(pc->arr[ret].age));
printf("请输入电话:>");
scanf("%s", pc->arr[ret].telephone);
printf("修改成功\n");
}
}
void SearchContact(const struct Contact* pc)
{
assert(pc);
char name[MAX_NAME];
printf("请输入要查找的人的名字:>");
scanf("%s", name);
int ret = FindByName(pc, name);
if (ret == -1)
printf("要查找的人不存在\n");
else
{
printf("%-20s\t%-5s\t%-5s\t%-12s\n", "姓名", "性别", "年龄", "电话");
printf("%-20s\t%-5s\t%-5d\t%-12s\n", pc->arr[ret].name,
pc->arr[ret].sex,
pc->arr[ret].age,
pc->arr[ret].telephone);
}
}
void ShowContact(const struct Contact* pc)
{
assert(pc);
int i = 0;
printf("%-20s\t%-5s\t%-5s\t%-12s\n", "姓名", "性别", "年龄", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5s\t%-5d\t%-12s\n", pc->arr[i].name,
pc->arr[i].sex,
pc->arr[i].age,
pc->arr[i].telephone);
}
}
int cmp_name(const void* e1, const void* e2)
{
return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
void SortContact(const struct Contact* pc)
{
assert(pc);
qsort(pc->arr, pc->sz, sizeof(pc->arr[0]), cmp_name);
printf("排序成功!结果如下:\n");
}
void Destroy(struct Contact* pc)
{
free(pc->arr);
pc->arr = NULL;
}
最终的代码
下面就给出有关test.c和contact.h的相关代码。 test.c
#include "contact.h"
enum ST
{
退出通讯录,
增加联系人,
删除联系人,
修改联系人,
查找联系人,
显示联系人,
排序联系人
};
void menu()
{
printf("****************************************\n");
printf("*****1.增加联系人 2.删除联系人*********\n");
printf("*****3.修改联系人 4.查找联系人*********\n");
printf("*****5.显示联系人 6.排序联系人*********\n");
printf("*****0.退出通讯录 *********\n");
printf("****************************************\n");
}
int main()
{
int input = 0;
struct Contact contact;
InitContact(&contact);
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 增加联系人:
ADDContact(&contact);
system("pause");
system("cls");
break;
case 删除联系人:
DeleContact(&contact);
system("pause");
system("cls");
break;
case 修改联系人:
ModifyContact(&contact);
system("pause");
system("cls");
break;
case 查找联系人:
SearchContact(&contact);
system("pause");
system("cls");
break;
case 显示联系人:
ShowContact(&contact);
system("pause");
system("cls");
break;
case 排序联系人:
SortContact(&contact);
ShowContact(&contact);
system("pause");
system("cls");
break;
case 0:
Destroy(&contact);
printf("再见!\n");
break;
default:
printf("选择错误,请重新选择!\n");
break;
}
} while (input);
return 0;
}
contact.h
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <windows.h>
#include <stdlib.h>
#define MAX_NAME 30
#define SEX 6
#define TelePhone 13
struct PeoInfo
{
char name[MAX_NAME];
char sex[SEX];
int age;
char telephone[TelePhone];
};
struct Contact
{
int sz;
struct PeoInfo* arr;
int capacity;
};
void InitContact(struct Contact* pc);
void ADDContact(struct Contact* pc);
void DeleContact(struct Contact* pc);
void ModifyContact(struct Contact* pc);
void SearchContact(const struct Contact* pc);
void ShowContact(const struct Contact* pc);
void SortContact(const struct Contact* pc);
void Destroy(struct Contact* pc);
热心老铁,在线答疑!
|