段友做的看电影网站,wordpress内容插件,vr 做的网站,优度网站建设引言
学会创建一个通讯录#xff0c;对过往知识进行加深和巩固。
文章很长#xff0c;要耐心学完哦#xff01; ✨ 猪巴戒#xff1a;个人主页✨ 所属专栏#xff1a;《C语言进阶》 #x1f388;跟着猪巴戒#xff0c;一起学习C语言#x1f388; 目录
引言
实战
建…引言
学会创建一个通讯录对过往知识进行加深和巩固。
文章很长要耐心学完哦 ✨ 猪巴戒个人主页✨ 所属专栏《C语言进阶》 跟着猪巴戒一起学习C语言 目录
引言
实战
建立文件
包含头文件
结构体的使用
通讯录
菜单
主脉络的实现
初始化函数的实现
第一个功能增加联系人到通讯录
第二个功能删除联系人的信息
第三个功能查找指定联系人
第四个功能修改指定联系人
第五个功能打印通讯录中信息
第六个功能排序通讯录中的内容
整体的代码实现 实战
通讯录的功能就是记录联系人的信息我们将联系人的信息分为5个部分分别是姓名、年龄、性别、手机号、地址。
建立文件
我们要将通讯录的功能实现首先要建立1个头文件2个源文件。 一个源文件的名字叫contact.c,用来存放实现通讯录功能的函数 另外一个源文件叫test.c用来实现通讯录的整体脉络 头文件叫做contact.h用来声明contact.c中的函数这样在test.c运行的时候就不会报出警告。 contact.h用来声明contact.c中的函数test.c就要包含contact.h,自己的头文件如下图包含
#include contact.h 包含头文件 既然test.c包含自己的头文件contact.h,为了简洁方便不妨把我们要使用的库函数的头文件包含在contact.h中.
contact.c也把contact.h头文件包含就不用再contact.c中再包含多个头文件了。 头文件会将功能函数声明放在里面供给test.c使用contact.c用来实现功能函数。 结构体的使用
我们要将联系人的5个信息储存起来而这5个信息的类型有不一样所以我们通过结构体将它们组合在一起 结构体结构是一些值的集合这些值被称为成员变量。结构的每个成员可以是不同类型的变量。 结构体的使用包含再两个源文件中所以我们将结构体的定义和声明放在contact.h头文件中。
typedef,关键字作用是为一个类型创建一个新的名字。
本来下面结构体的类型是struct PeoInfo为了将名字简化用到了typedef关键字。
typedef struct PeoInfo
{char name[100];int age;char sex[10];char tele[12];char addr[30];
}PeoInfo; #define ,为了更好改变name,sex,tele,addr的最大容量通过定义宏将参数替换。 MAX 表示最大能容纳的联系人个数 MAX_NAME 表示name最大能容纳的字符个数 MAX_SEX 表示sex最大能容纳的字符个数 MAX_TELE 表示tele最大能容纳的字符个数 MAX_ADDR 表示addr最大能容纳的字符个数 #define MAX 100
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo; 通讯录
存放在头文件contact.h
通讯录不仅要包含上面的5个信息5个信息包含在一起就是一个人的信息。创建变量count可以记录通讯录的实际人数之后的打印功能也要使用count来打印。
data是struct PeoInfo类型的数组。上面把struct PeoInfo简化为PeoInfo.
data是储存每个人信息的数组数组的每个元素代表着一个人的信息。
typedef struct Contact
{PeoInfo data[MAX];int count;//记录当前通讯录中实际人数的个数
}Contact; 菜单
存放在test.c源文件
首先给用户呈现的是菜单菜单记录着用户可供选择的功能将功能可视化。 一共包含6个功能 增加联系人到通讯录删除联系人的信息查找指定联系人修改指定联系人打印通讯录中信息排序通讯录中的内容 0.退出通讯录 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);} 主脉络的实现
存放在test.c
input为键盘输入的数字选择不同的数字代表着不同的功能。
switch语句分支语句实现input为不同的数字选择不同的功能在case 后面实现这六个功能。
创建新的结构体变量要进行初始化InitContact(con)就是用来初始化结构体的。
之所以用自定义函数InitContact,是为了简洁和模块化处理。
int main()
{int input 0;Contact con;//初始化通讯录:模块化初始化InitContact(con);//只能传地址进行修改scanf(%d,input);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:printf(退出通讯录\n);break;default:printf(选择错误\n);}} while (input);return 0;
} 初始化函数的实现
存放在源文件contact.c
assert用来检验pc是否为空指针如果为空指针就会报错。头文件assert.h
memset功能是填充内存块将num个字节的value填充到起始地址为ptr的位置。 void InitContact(Contact* pc)
{assert(pc);pc-count 0;memset(pc-data, 0, sizeof(pc-data));
} test.c要想使用就要在头文件contact.h中进行声明。
void InitContact(Contact* pc); 第一个功能增加联系人到通讯录
功能函数的实现都会放在contact.c中。
assert用来检验pc是否为空指针如果为空指针就会报错。头文件assert.h
Contact* pc是传过来的struct Contact 类型的变量的地址这里是传址调用可以改变原来结构体的内容。
如果count到了通讯录的最大容量就不能添加信息了退出函数并发出提示。
原始的count是0每添加一个人的信息count就要加1。
新的count表示的就是新联系人的下标通过pc-data[pc-count].name 的方式找到各个信息。
如果count已经达到最大值那么就直接提示 “通讯录已满无法添加” 并结束函数。
函数实现
void AddContact(Contact* pc)
{assert(pc);if (pc-count MAX){printf(通讯录已满无法添加\n);return;}printf(请输入名字》);scanf(%s, pc-data[pc-count].name);printf(请输入年龄》);scanf(%d, (pc-data[pc-count].age));printf(请输入性别);scanf(%s, pc-data[pc-count].sex);printf(请输入电话);scanf(%s, pc-data[pc-count].tele);printf(请输入地址);scanf(%s, pc-data[pc-count].addr);pc-count; printf(增加成功\n);
} 第二个功能删除联系人的信息
assert用来检验pc是否为空指针如果为空指针就会报错。头文件assert.h
Contact* pc是传过来的struct Contact 类型的变量的地址这里是传址调用可以改变原来结构体的内容。
如果count为0就表示通讯录里面没有内容也就不能删除。直接提示 通讯录为空没有信息可以删除 然后退出函数。
要删除联系人的信息首先要查找联系人之后才能删除。所以要实现查找联系人的功能。
1.查找
2.删除
查找FindByName函数实现
创建一个字符函数name向name输入我们要查找的联系人名字之后用name来进行对比。
首先输入要查找的联系人名字通过下标 i 对data进行查找直到找到返回下标或者返回-1.
名字是字符数组用strcmp对进行比较名字库函数strcmp只有在相等的时候返回0。
strcmp的头文件string.h 删除DelContact来实现
找到要删除的联系人的下标我们将它后面联系人的信息覆盖掉要删除的联系人的信息就可以达到目的然后对count减一这样count就可以表示联系人的个数了。
本来最后一位的联系人的信息不用进行操作本来count是99下标为99的联系人信息覆盖到下标为98的位置下标为99的信息不用管count--之后count 98下标为99的数据就不会被我们使用到。
函数实现
static int FindByName(Contact* pc,char name[])
{assert(pc);int i 0;for (i 0; i pc-count; i){if (0 strcmp(pc-data[i].name, name)){return i;}}return -1;
}
void DelContact(Contact* pc)
{char name[MAX_NAME] { 0 };assert(pc);int i 0;if (pc-count 0){printf(通讯录为空没有信息可以删除\n);return;}printf(请输入要删除人的名字);scanf(%s, name);//删除//1.查找int pos FindByName(pc, name);if (pos -1){printf(要删除的人不存在\n);return;}//2.删除for (i pos; i pc-count; i){pc-data[i] pc-data[i 1];}pc-count--;
} 第三个功能查找指定联系人 assert用来检验pc是否为空指针如果为空指针就会报错。头文件assert.h
Contact* pc是传过来的struct Contact 类型的变量的地址这里是传址调用可以改变原来结构体的内容。
建立字符数组name输入要查找的联系人的信息。通过FindByName对name进行查找。
FindByName在上个功能实现了当找到联系人的信息返回下标。没找到返回-1。
我们用pos来对FindByName的返回值进行回收如果pos等于-1提示 要查找的人不存在然后
函数实现
void SeachContact(Contact* pc)
{assert(pc);char name[MAX_NAME] { 0 };printf(请输入需要查找的联系人的名字:);scanf(%s, name);//1.查找int pos FindByName(pc, name);if (pos -1){printf(要查找的人不存在\n);return;}//2.打印printf(%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n, 名字, 年龄, 性别, 电话, 地址);printf(%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n, pc-data[pos].name,pc-data[pos].age,pc-data[pos].sex,pc-data[pos].tele,pc-data[pos].addr);}第四个功能修改指定联系人
assert检验空指针name用来接收要修改联系人的姓名通过 FindByName 查找联系人pos返回查找结果。Contact* pc是传过来的struct Contact 类型的变量的地址这里是传址调用可以改变原来结构体的内容。
找到结果会返回下标pos得到下标用ps-data[pos].name就可以修改内容了。
函数实现
void ModifyContact(Contact* pc)
{assert(pc);char name[MAX_NAME] { 0 };printf(请输入需要查找的联系人的名字:);scanf(%s, name);//1.查找int pos FindByName(pc, name);if (pos -1){printf(要查找的人不存在\n);return;}printf(要修改人的信息已经找到接下来进行修改\n);//2.修改printf(请输入名字》);scanf(%s, pc-data[pos].name);printf(请输入年龄》);scanf(%d, (pc-data[pos].age));printf(请输入性别);scanf(%s, pc-data[pos].sex);printf(请输入电话);scanf(%s, pc-data[pos].tele);printf(请输入地址);scanf(%s, pc-data[pos].addr);printf(修改成功\n);
} 第五个功能打印通讯录中信息
assert检验空指针。为了对齐联系人的数据数据以最大容纳量来进行打印。
%20就是按照20个字符打印%-20就是左对齐的意思。 函数实现
void ShowContact(const Contact* pc)
{assert(pc);int i 0;//一个汉字是两个字符printf(%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n, 名字, 年龄, 性别, 电话, 地址);for (i 0; i pc-count; i){printf(%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n, pc-data[i].name,pc-data[i].age,pc-data[i].sex,pc-data[i].tele, pc-data[i].addr);}
} 第六个功能排序通讯录中的内容
assert检验空指针。qsort是快速排列函数。base是要排序的起始地址pc-data表示首元素地址。num是要比较的元素个数通讯录有多少个人就比较多少个元素num为pc-count。按名字排序compar要比较的是通讯录的名字我们实现cmp_peo_by_name函数到时候把这个函数传过去。
cmp_peo_by_name比较名字函数名字是字符串通过strcmp对字符串进行比较。
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*)) 函数实现
int cmp_peo_by_name(const void* e1, const void* e2)
{return strcmp( ((PeoInfo*)e1)-name , ((PeoInfo*)e2)-name );
}
//按照名字来排序
void SortContact(Contact* pc)
{assert(pc);qsort(pc-data, pc-count, sizeof(PeoInfo), cmp_peo_by_name );printf(排序成功\n);
} 整体的代码实现
test.c
#define _CRT_SECURE_NO_WARNINGS#include contact.h//
//1.静态的版本
//2.动态的版本
//3.文件的版本
//
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;Contact con;//初始化通讯录:模块化初始化InitContact(con);//只能传地址进行修改do{menu();printf(请选择》);scanf(%d, input);switch (input){case 1:AddContact(con);break;case 2:DelContact(con);break;case 3:SeachContact(con);break;case 4:ModifyContact(con);break;case 5:ShowContact(con);break;case 6:SortContact(con);break;case 0:printf(退出通讯录\n);break;default:printf(选择错误\n);}} while (input);return 0;
}
contact.c
#define _CRT_SECURE_NO_WARNINGS#include contact.h
void InitContact(Contact* pc)
{assert(pc);pc-count 0;memset(pc-data, 0, sizeof(pc-data));
}void AddContact(Contact* pc)
{assert(pc);if (pc-count MAX){printf(通讯录已满无法添加\n);return;}printf(请输入名字》);scanf(%s, pc-data[pc-count].name);printf(请输入年龄》);scanf(%d, (pc-data[pc-count].age));printf(请输入性别);scanf(%s, pc-data[pc-count].sex);printf(请输入电话);scanf(%s, pc-data[pc-count].tele);printf(请输入地址);scanf(%s, pc-data[pc-count].addr);pc-count; printf(增加成功\n);
}void ShowContact(const Contact* pc)
{assert(pc);int i 0;//一个汉字是两个字符printf(%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n, 名字, 年龄, 性别, 电话, 地址);for (i 0; i pc-count; i){printf(%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n, pc-data[i].name,pc-data[i].age,pc-data[i].sex,pc-data[i].tele, pc-data[i].addr);}
}static int FindByName(Contact* pc,char name[])
{assert(pc);int i 0;for (i 0; i pc-count; i){if (0 strcmp(pc-data[i].name, name)){return i;}}return -1;
}void DelContact(Contact* pc)
{char name[MAX_NAME] { 0 };assert(pc);int i 0;if (pc-count 0){printf(通讯录为空没有信息可以删除\n);return;}printf(请输入要删除人的名字);scanf(%s, name);//删除//1.查找int pos FindByName(pc, name);if (pos -1){printf(要删除的人不存在\n);return;}//2.删除for (i pos; i pc-count; i){pc-data[i] pc-data[i 1];}pc-count--;
}void SeachContact(Contact* pc)
{assert(pc);char name[MAX_NAME] { 0 };printf(请输入需要查找的联系人的名字:);scanf(%s, name);//1.查找int pos FindByName(pc, name);if (pos -1){printf(要查找的人不存在\n);return;}//2.打印printf(%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n, 名字, 年龄, 性别, 电话, 地址);printf(%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n, pc-data[pos].name,pc-data[pos].age,pc-data[pos].sex,pc-data[pos].tele,pc-data[pos].addr);}void ModifyContact(Contact* pc)
{assert(pc);char name[MAX_NAME] { 0 };printf(请输入需要查找的联系人的名字:);scanf(%s, name);//1.查找int pos FindByName(pc, name);if (pos -1){printf(要查找的人不存在\n);return;}printf(要修改人的信息已经找到接下来进行修改\n);//2.修改printf(请输入名字》);scanf(%s, pc-data[pos].name);printf(请输入年龄》);scanf(%d, (pc-data[pos].age));printf(请输入性别);scanf(%s, pc-data[pos].sex);printf(请输入电话);scanf(%s, pc-data[pos].tele);printf(请输入地址);scanf(%s, pc-data[pos].addr);printf(修改成功\n);
}int cmp_peo_by_name(const void* e1, const void* e2)
{return strcmp( ((PeoInfo*)e1)-name , ((PeoInfo*)e2)-name );
}
//按照名字来排序
void SortContact(Contact* pc)
{assert(pc);qsort(pc-data, pc-count, sizeof(PeoInfo), cmp_peo_by_name );printf(排序成功\n);
} contact.h
#pragma once#include string.h
#include stdio.h
#include assert.h
#include stdlib.h#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30//类型的声明
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;//通讯录
typedef struct Contact
{PeoInfo data[MAX];int count;//记录当前通讯录中实际人数的个数
}Contact;//初始化通讯录
void InitContact(Contact* pc);//增加联系人到通讯录
void AddContact(Contact* pc);//打印通讯录中信息
void ShowContact(const Contact* pc);//删除联系人的信息
void DelContact(Contact* pc);//查找指定联系人
void SeachContact(Contact* pc);//修改指定联系人
void ModifyContact(Contact* pc);//排序通讯录中的内容
//按照名字来排序
void SortContact(Contact* pc);