1.模拟实现通讯录总体架构一览图

2.文件执行任务

3.分模块实现
测试模块 test.c
1.为了更好地展示,制作一个菜单,在菜单中有 添加,删除,查找,修改,排序,清空,退出的选项。 2.因为起先要进入程序一趟,所以用do····while循环(输入选项来看具体操作,退出还是其他操作)
#include "contact.h"
void menu()
{
printf("*****************************************\n");
printf("******** Contact ******\n");
printf("******** 1.add 2. del ******\n");
printf("******** 3.search 4.modify ******\n");
printf("******** 5.print 6.empty ******\n");
printf("******** 7.sort 0.exit ******\n");
printf("*****************************************\n");
}
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
PRINT,
EMPTY,
SORT,
};
int main()
{
int input = 0;
contact con;
InitContact(&con);
do
{
menu();
printf("请选择>");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case PRINT:
PrintContact(&con);
break;
case SORT:
SortContact(&con);
break;
case EMPTY:
EmptyContact(&con);
break;
case EXIT:
ExitContact(&con);
break;
default:
printf("输入错误,请重新输入\n");
}
} while (input);
return 0;
}
头文件 功能函数声明 contact.h
1.声明各类功能函数 2.定义各个常量,把常量定义成通俗易懂的变量,便于在多处使用。 3.定义结构体,自定义类型中,有一个联系人的基本信息。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 20
#define MAX 1000
#define IN_NUM 3
#define SET_NUM 2
typedef struct base
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
}base;
typedef struct contact
{
int sz;
base* data;
int capciaty;
}contact;
void InitContact(contact* pc);
void AddContact(contact* pc);
void PrintContact(contact* pc);
void DelContact(contact* pc);
void SearchContact(contact* pc);
void ModifyContact(contact* pc);
void SortContact(contact* pc);
void EmptyContact(contact* pc);
void ExitContact(contact* pc);
功能函数逐一实现 contact.c
1.初始化通讯录
动态申请空间 默认在动态空间中存放3个基本单位信息
void InitContact(contact* pc)
{
pc->data = (base*)malloc(sizeof(base) * IN_NUM);
if (pc->data == NULL)
{
perror("InitContact");
return;
}
pc->sz = 0;
pc->capciaty = IN_NUM;
}
2.添加联系人
当默认的空间被装满时,然后以后的每一次都开辟两个基本空间
void AddContact(contact* pc)
{
//先判断通讯录中是否满了
//if (pc->sz == MAX)
//{
// printf("通讯录已满,无法添加\n");
// return;
//}
//动态判断人的个数是否满足3
if (pc->sz == pc->capciaty)
{
printf("开始增容:\n");
//从新设置一个指针,存放新开辟的内存
base* ptr = (base*)realloc(pc->data, (pc->capciaty + SET_NUM) * sizeof(base));
//判断是否开辟成功
if (ptr == NULL)
{
printf("开辟失败\n");
perror("AddContact");
return;
}
else
{
printf("开辟成功\n");
//开辟成功的话,把ptr转交给data来维护,这样在内存释放的时候只需要释放pc->data
pc->data = ptr;
//增加基本信息数量
pc->capciaty += SET_NUM;
}
printf("增容完毕\n");
}
//添加
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++;
printf("添加成功\n");
}
3.显示联系人信息
逐一打印联系人信息,注意之间的距离(保持美观)
void PrintContact(contact* pc)
{
printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址");
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-20s %-10s %-5d %-15s %-20s\n",
pc->data[i].name,
pc->data[i].sex,
pc->data[i].age,
pc->data[i].tele,
pc->data[i].addr);
}
}
4.删除联系人
在删除联系人之前,首先要查找要删除联系人的名字,然后进行删除,注意如何删除 让删除的这个单位的后一个单位去覆盖这个删除的单位(这样原来要删除的地方变成了后面一个值) i = i+1 当通讯录中有被删除着的名字时,返回这个单位的下标 当通讯录中没有时,返回-1
static int Find_name(contact* pc, char name[])
{
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)
{
if (pc->sz == 0)
{
printf("通讯为空,无需删除\n");
return;
}
char name[MAX_NAME];
printf("请输入要删除联系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("该联系人不存在\n");
return;
}
for (int i = ret; i < pc->sz; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
4.查找联系人
在删除联系人的时候有查找函数,在这里直接引用,并打印。这个人的信息。
void SearchContact(contact* pc)
{
char name[MAX_NAME];
printf("请输入要查找联系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("该联系人不存在\n");
return;
}
printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址");
printf("%-20s %-10s %-5d %-15s %-20s\n", pc->data[ret].name,
pc->data[ret].sex,
pc->data[ret].age,
pc->data[ret].tele,
pc->data[ret].addr);
}
5.修该联系人信息
还是现在通讯录中查找这个联系人,在进行输入修改
void ModifyContact(contact* pc)
{
char name[MAX_NAME];
printf("请输入要修改联系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("该联系人不存在\n");
return;
}
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].addr);
}
6.排序联系人姓名
利用冒泡排序对联系人的名字进行排序(也可以使用快排)
static void SwapByname(base* pa, base* pb)
{
base b;
b = *pa;
*pa = *pb;
*pb = b;
}
void SortContact(contact* pc)
{
printf("开始排序\n");
int i = 0;
int j = 0;
for (i = 0; i < pc->sz; i++)
{
for (j = 0; j < pc-> sz - i - 1; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
SwapByname(&pc->data[j], &pc->data[j + 1]);
}
}
}
printf("排序结束\n");
}
7.清空联系人
在这里直接使用sz–,就可以删除
void EmptyContact(contact* pc)
{
if (pc->sz == 0)
{
printf("通讯录为空,无需清空\n");
return;
}
printf("开始清除数据:\n");
int num = pc->sz;
for (int i = 0; i < num; i++)
{
pc->sz--;
}
printf("清空完毕\n");
}
8.退出通讯录
手动开辟,手动释放
void ExitContact(contact* pc)
{
free(pc->data);
pc->data = NULL;
pc->sz = 0;
pc->capciaty = 0;
}
运行展示: 
|