这种项目就是构建框架,分装函数实现各个功能,千万不要想的太复杂!!
我们先来看整个流程
1:main函数基本框架构建
2:先用结构体表示一个人的信息,这是一个结构体
3:通讯录肯定要存多个人(假设容量为100人),所以我们要创建一个结构体数组(里面相当于100个这样的结构体)
4:全部初始化,如果不初始化,那么编译器就会放入随机值,所以我们全部初始化为0
5:实现各个功能:添加联系人,显示所有联系人,删除联系人,修改联系人信息,整理存放顺序
以上是基本功能,在了解思路后,可以自行添加!
(完整代码我放在最后)
唯一要注意的是:在使用结构体时,需要清楚指针指向结构体内容的方式
基本框架构建
我们从main函数开始,肯定要让用户进行选择操作,因此我们可以用do....while()循环和switch分支来构建,这个框架以后可以通用,也很简单,比如:
咋样,以上的思路很简单吧,那么我们进行下一步!
结构体和结构体数组的构建
我们先写出一个人的结构体样式:
注意:typedef的作用就是可以直接使用一个名字来代表这个结构体比如Information,而不用写struct Information
创建完一个人的,我们需要使用另外一个结构体来放结构体数组来表示100个人的:
(意思就是创建一个结构体,里面放结构体数组,里面有100个这样的单个结构体)
类型+名字+数量(这个可以理解为数组,只是变化了类型)
注意:sz 是用来控制下标的
MAX 是用 #define 定义的全局变量,等于100
全部初始化
这个我们很好理解,因为还没有存储嘛,所以结构体数组里面全部是 0
memset库函数就是将结构体数组全部初始化为0的一个功能:
它需要三个参数:开始地址,改变内容,改变的空间(字节)
实现各个功能
显示联系人 功能
1:判断是否可以显示
2:将已经填充的 结构体数组内容 打印出来
函数传参:
函数声明:
函数实现:
输入联系人 功能
1:判断 结构体数组 是否已经存满
2:循环 输入各项信息
函数传参:
函数声明:
函数实现:
删除联系人 功能
1:判断是否存储的有联系人 (我这里多此一举啊!大家不要学!!!)
2:判断是否可以删除
3:for循环查找输入要删除的联系人,然后把下标传给另外一个变量,再用指针修改,修改后他后面的联系人向前挪动
函数传参:
函数声明:
函数实现:
修改 功能
1:判断是否存在这个联系人
2:选择修改类型,比如是年龄还是地址
3:修改内容
函数传参:
函数声明:
函数实现:
整理 功能
这个就是qsort库函数用来排序结构体内容的
函数传参:
函数声明:
函数实现:
这里要注意的就是:
qsort函数传的首地址是:pc->people 现在指针指向的就是结构体数组首元素地址,那么我们排序排的是名字,名字这个结构体的类型是Information*那么我们指针强转,强转的类型也是单个结构体的类型 Information* 然后再指向这个结构体里的变量
注意:强转的类型不是struct Commun*,因为我们排的是名字,名字是在struct Information这个结构体里面的
完整代码
分别是 : ( 框架 头文件 函数具体实现)
框架
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"Addbook.h"
int main()
{
//通讯库
Commun perliminary;
//初始化通讯库
perlimin(&perliminary);
int input = 0;
do
{
printf("**** 0:Out(退出) **********\n");
printf("**** 1:Search(显示信息) ********\n");
printf("**** 2:Storage(输入信息)*******\n");
printf("**** 3:Delete(删除联系人) *******\n");
printf("***** 4:Modify(修改联系人) *******\n");
printf("***** 5:Modify(整理联系人) *******\n");
printf("请选择操作");
scanf("%d", &input);
switch (input)
{
case 1:
Notice(&perliminary);
break;
case 2:
inport(&perliminary);
break;
case 3:
Permit(&perliminary);
break;
case 4:
Modify(&perliminary);
break;
case 5:
Adjust(&perliminary);
break;
default:
printf("重新选择\n");
break;
case 0:
printf("退出通讯录\n");
break;
}
printf("\n");
} while (input);
return 0;
}
头文件
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX 100
//单个人的信息
typedef struct Information
{
char Name[20];
int Age;
char Gender;//性别
char Address[20];//地址
char Phone[12];//电话
}Information;
//能放100个人的通讯信息
typedef struct Commun
{
Information people[MAX];
int sz;
}Commun;
//通讯库的初始化
void perlimin(struct Commun* pc);
//输入信息
void inport(struct Commun* pc);
//显示信息
void Notice(struct Commun* pc);
//删除联系人
void Permit(struct Commun* pc);
//修改联系人的信息
void Modify(struct Commun* pc);
//整理信息
void Adjust(struct Commun* pc);
函数具体实现
#define _CRT_SECURE_NO_WARNINGS 1
#include"Addbook.h"
//先将每个人的信息初始化为0
void perlimin(struct Commun* pc)
{
pc->sz = 0;
memset(pc->people, 0, sizeof(pc->people));
}
//输入信息
void inport(struct Commun* pc)
{
//可以循环输入
int input = 0;
do
{
printf("选择1开始输入,选择0退出输入\n");
scanf("%d", &input);
//判断是否能输入
if (pc->sz == MAX)
{
printf("抱歉,通讯录已满,无法输入\n");
return;
}
switch (input)
{
case 1:
//否则可以输入
printf("请输入姓名->");
scanf("%s", pc->people[pc->sz].Name);
printf("请输入年龄->");
scanf("%d", &pc->people[pc->sz].Age);
printf("请输入性别->");
getchar();
scanf("%c", &pc->people[pc->sz].Gender);
printf("请输入地址->");
scanf("%s", pc->people[pc->sz].Address);
printf("请输入电话->");
scanf("%s", pc->people[pc->sz].Phone);
(pc->sz)++;
break;
case 0:
printf("输入成功\n");
break;
}
} while (input);
}
//显示信息
void Notice(struct Commun* pc)
{
//判断是否有信息,否则显示没有
if (pc->sz == 0)
{
printf("抱歉显示失败,没有存储联系人\n");
return;
}
printf("%10s\t%s\t%s\t%15s\t%12s", "姓名", "年龄", "性别", "地址", "电话");
printf("\n");
//否则显示各人信息
for (int i = 0; i < pc->sz; i++)
{
printf("%10s\t%d\t%c\t%15s\t%12s\n", pc->people[i].Name,
pc->people[i].Age,
pc->people[i].Gender,
pc->people[i].Address,
pc->people[i].Phone);
}
}
//删除联系人
void Permit(struct Commun* pc)
{
char Name[15];
//判断是否有信息,否则无法删除
if (pc->sz == 0)
{
printf("抱歉删除失败,没有存储联系人\n");
return;
}
//否则可以删除
printf("请输入要删除的联系人的名字\n");
scanf("%s", Name);
int index = -1;
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(Name, pc->people[i].Name) == 0)
{
index = i;
break;
}
}
if (index != -1)
{
// 找到了开始删除
for (int i = index + 1; i < pc->sz; i++) {
pc->people[i - 1] = pc->people[i];
}
pc->sz--;
printf("删除成功,请选择下一步操作\n");
}
else
{
printf("删除失败,没有找到匹配内容,请选择下一步操作\n");
}
}
//修改联系人的信息
void Modify(struct Commun* pc)
{
int i = 0;
int input = 0;
int ret = 1;
char Name[15];
printf("请输入要修改的联系人的名字,进行查询\n");
scanf("%s", Name);
//判断是否存在这个联系人
for (i = 0; i < pc->sz - 1; i++)
{
if (strcmp(Name, pc->people[i].Name) == 0 )
{
//等于0,说明找到了,就结束循环
ret = 0;
}
}
//判断是否存在这个联系人
if (ret == 0)
{
printf("查询成功,请输入要修改的联系人信息\n");
}
if (ret !=0 )
{
printf("查询失败,没有该联系人\n");
return;
}
//如果存在,更改信息
printf("查询成功!可选择更改 1:姓名 2:年龄 3:性别 4:地址 5:电话\n");
scanf("%d", &input);
switch (input)
{
case 1:
memset(pc->people[i].Name, 0, sizeof(pc->people[i].Name));
printf("请输入更改后的姓名\n");
scanf("%s",&pc->people[i].Name);
break;
case 2:
memset(pc->people[i].Age, 0, sizeof(pc->people[i].Age));
printf("请输入更改后的年龄\n");
scanf("%s", pc->people[i].Age);
break;
case 3:
memset(pc->people[i].Gender, 0, sizeof(pc->people[i].Gender));
printf("请输入更改后的性别\n");
scanf("%s", pc->people[i].Gender);
break;
case 4:
memset(pc->people[i].Address, 0, sizeof(pc->people[i].Address));
printf("请输入更改后的地址\n");
scanf("%s", &pc->people[i].Address);
break;
case 5:
memset(pc->people[i].Phone, 0, sizeof(pc->people[i].Phone));
printf("请输入更改后的电话\n");
scanf("%s", &pc->people[i].Phone);
break;
}
printf("更改成功!\n");
}
//qsort排序函数
int compare(const void* p1, const void* p2)
{
//return strcmp(((const struct Commun*)p1->people).Name, ((const struct Commun*)p2->people).Name);
return strcmp(((const Information*)p1)->Name, ((const Information*)p2)->Name);
}
//整理联系人
void Adjust(struct Commun* pc)
{
//判断是否有信息,否则无法整理
if (pc->sz == 0)
{
printf("抱歉整理失败,没有存储联系人\n");
return;
}
//否则可以整理
// 这里传入的是pc->people,那么实际是将 Information 的数组首元素传入了,所以类型是Information*,而不是struct Commun*
qsort(pc->people, pc->sz, sizeof(pc->people[pc->sz]), compare);
printf("整理成功\n");
}