✨ 写在前面
🎃 哈喽 大家好👋👋👋
🌱 作为一个初入编程的大学生,知识浅薄,但还是要学习大佬写一下前言滴(🤭)
🌱 我的其他文章
1.【C语言】字符串函数使用+模拟【上】
2.【C语言】彻底搞明白C语言一大关卡—C指针【初阶】
3.【C语言】字符串操作函数&&字符串查找&&内存操作函数【下】🌱 初入编程的世界 前方"路漫漫"🛣️ 每天我们都要进步一点点💧
🌱 希望分享知识的同时可以和你们一起进步🍻
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
⭐⭐这里是目录⭐⭐
📜1.准备工作
创建好工程以后 我们进行分模块编写
1.test.c---->用于测试代码逻辑
2.contact.c---->用于实现各种函数功能
3.contact.h------>各种头文件以及结构的声明
如图所示
📜2. 定义结构体
分析:
1.联系人信息结构体: 我们需要一个结构体来存储1000个联系人的信息
其中包含 :
1)姓名--字符串类型
2)性别---字符串类型
3)年龄--int类型
4)电话---字符串类型
5) 地址---字符串类型
2. 通讯录结构体:
其中包含:
1)联系人结构体
2)当前存的联系人的个数
而有时候我们需要更改一些信息 就不方便去代码中一个一个去改,比如说 名字的最大长度....等
所以我们可以用#define定义 如果以后想改 直接改#define部分就可以了!
📜3. 明确好我们想要实现的功能:
0.退出通讯录
1.增加联系人
2.删除联系人
3.查找联系人
4.修改联系人
5.对联系人进行排序
6.打印联系人
7.清楚联系人
还有 初始化通讯录
根据我们想要实现的功能 和 命名的可读性 我们可以把需要的函数定义出来
注意:我们需要对定义的通讯录
📜4.根据功能把菜单写好,这里和之前的三子棋逻辑差不多
这里我们使用枚举常量 和switch语句结合使用
这样 代码清晰易懂 我们一看就知道switch进入了什么语句
否则 case 0,case 1 等 降低了代码的可读性
注意:别忘了包含contact.h ,里面有stdio.h等头文件
📜5.实现各功能函数
🏷️5.1 通讯录初始化
🏷️5.2 通讯录增加联系人
🏷️ 5.3 通讯录打印
🏷️5.4 查找联系人
这里 重新封装一个查找函数 因为后面的修改联系人 也需要先找到该联系人的下标
🏷️5.5 修改联系人
这里可以从函数内部再弄一个菜单, 提示用户修改什么
老样子 使用枚举
除了修改年龄 修改其他的其实都差不多
这里注意 我们修改联系人也需要先找到联系人所在的下标 然后才能进行修改!
🔖 5.5.1 修改姓名(同修改性别,电话,地址)
把之前的 名字(性别,电话,地址) 用memset函数置为0
然后把修改后的 名字(性别,电话,地址) 用memcpy拷贝进去就可以了
其他的类似 直接放在总代码啦
🔖5.5.2 修改年龄
由于年龄是int类型 所以直接赋值代替原来的值就可以了
🏷️5.6 删除联系人
🏷️5.7 排序
这里可以利用快速排序 封装成不同函数
可以根据名字,性别,年龄等进行排序
🏷️5.8 清除
📜6.总代码
📇1.contact.h
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
//定义结构体
typedef struct PeoInfo {
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tele[TELE_MAX];
char addr[ADDR_MAX];
}PeoInfo;
typedef struct Contact {
PeoInfo data[MAX];
int size;
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//打印
void PrintContact(Contact* pc);
//查找
void FindContact(Contact* pc);
//修改
void ModifyContact(Contact* pc);
//删除
void DeleteContact(Contact* pc);
//排序
void SortContact(Contact* pc);
//清除
void ClearContact(Contact* pc);
📇2.test.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include"contact.h"
//利用枚举常量
enum Option {
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT,
CLEAR
};
void menu()
{
printf("*********************************************\n");
printf("*********** 1.Add 2.Del ************\n");
printf("*********** 3.Search 4.Modiyf ************\n");
printf("*********** 5.sort 6.print ************\n");
printf("************ 7.clear 0.exit ************\n");
printf("*********************************************\n");
}
//测试通讯录
void test()
{
int input = 0;
Contact con = { 0 };
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case EXIT:
break;
case ADD:
AddContact(&con);
break;
case DEL:
DeleteContact(&con);
break;
case SEARCH:
FindContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SORT:
SortContact(&con);
break;
case PRINT:
PrintContact(&con);
break;
case CLEAR:
break;
default:
printf("输入错误,请重新输入:");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
📇3.contact.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include"contact.h"
//通讯录初始化
void InitContact(Contact* pc)
{
assert(pc);
pc->size = 0;//初始联系人为0
//利用memset 把PeoInfo中内存设置为0
memset(pc->data, 0, sizeof(PeoInfo) * MAX);
}
//通讯录 打印
void PrintContact(Contact* pc)
{
assert(pc);
printf("<------------------------------------------->\n");
printf("%-7s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
int i = 0;
for (i = 0; i < pc->size; i++)
{
printf("%-7s %-5s %-5d %-12s %-30s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,
pc->data[i].tele,pc->data[i].addr);
}
printf("<------------------------------------------->\n");
}
//增加联系人
void AddContact(Contact* pc)
{
assert(pc);
//首先判断一下 是不是满了
if (pc->size == MAX)
{
printf("通讯录已经满了,无法添加联系人\n");
return;//既然已经满了,就返回
}
//如果没满,正常添加联系人
printf("请输入联系人姓名:");
scanf("%s",pc->data[pc->size].name);//pc->data[pc->size]---得到当前结构体
printf("请输入联系人性别:");
scanf("%s", pc->data[pc->size].sex);
printf("请输入联系人年龄:");
scanf("%d", &(pc->data[pc->size].age));//注意这里是得到年龄的地址!
printf("请输入联系人电话:");
scanf("%s", pc->data[pc->size].tele);
printf("请输入联系人地址:");
scanf("%s", pc->data[pc->size].addr);
//pc->size处存放完毕 size++
pc->size++;
printf("添加成功\n");
}
//查找某个联系人
//查找应该重新封装一个函数 用于找到联系人所在位置
int FindByName(Contact* pc, char* name)
{
for (int i = 0; i < pc->size; i++)
{
if (strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
//找不到返回-1
return -1;
}
void FindContact(Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("请输入你要查找人的姓名:");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("找不到联系人\n");
return;
}
//如果找到了 打印信息
printf("%-7s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-7s %-5s %-5d %-12s %-30s\n", pc->data[pos].name, pc->data[pos].sex,
pc->data[pos].age,pc->data[pos].tele, pc->data[pos].addr);
}
enum MODIFY_OP {
EXIT,
NAME,
SEX,
AGE,
TELE,
ADDR
};
static menu_modify()
{
printf("*********************************************\n");
printf("*********** 1.name 2.sex ******************\n");
printf("*********** 3.age 4.tele ******************\n");
printf("*********** 5.addr 0.exit ******************\n");
printf("*********************************************\n");
}
//修改姓名
static void ModifyName(Contact* pc,int pos)
{
char name[NAME_MAX] = { 0 };
printf("请输入修改后的姓名:");
scanf("%s", name);
//由于名字长度不一定相同 所以先把原来的名字置为0
memset(pc->data[pos].name, 0,sizeof(char)*NAME_MAX);
//然后利用memcpy拷贝----拷贝的大小是 修改后的名字字符长度
memcpy(pc->data[pos].name, name, sizeof(name));
printf("修改成功\n");
}
//修改性别
static void ModifySex(Contact* pc, int pos)
{
char sex[SEX_MAX] = { 0 };
printf("请输入修改后的性别:");
scanf("%s", sex);
memset(pc->data[pos].sex, 0, sizeof(char) * SEX_MAX);
memcpy(pc->data[pos].sex, sex, sizeof(sex));
printf("修改成功\n");
}
//修改年龄
static void ModifyAge(Contact* pc, int pos)
{
int age = 0;
printf("请输入修改后的年龄:");
scanf("%d",&age);
//修改年龄很简单 只需要赋值替换掉原来的值就可以了
pc->data[pos].age = age;
printf("修改成功\n");
}
//修改电话
static void ModifyTele(Contact* pc, int pos)
{
char tele[TELE_MAX] = { 0 };
printf("请输入修改后的电话:");
scanf("%s", tele);
memset(pc->data[pos].tele, 0, sizeof(char) * TELE_MAX);
memcpy(pc->data[pos].tele, tele, sizeof(tele));
printf("修改成功\n");
}
//修改地址
static void ModifyAddr(Contact* pc, int pos)
{
char addr[ADDR_MAX] = { 0 };
printf("请输入修改后的地址:");
scanf("%s", addr);
memset(pc->data[pos].addr, 0, sizeof(char) * ADDR_MAX);
memcpy(pc->data[pos].addr, addr, sizeof(addr));
printf("修改成功\n");
}
//修改联系人
void ModifyContact(Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("请输入要修改的联系人:");
scanf("%s", name);
//先找到联系人
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("不存在联系人\n");
return;
}
int input = 0;
do
{
menu_modify();
printf("请输入要修改的内容:\n");
scanf("%d", &input);
switch (input)
{
case EXIT:
printf("已退出修改\n");
break;
case NAME:
ModifyName(pc,pos);
break;
case SEX:
ModifySex(pc,pos);
break;
case AGE:
ModifyAge(pc,pos);
break;
case TELE:
ModifyTele(pc, pos);
break;
case ADDR:
ModifyAddr(pc, pos);
break;
default:
printf("输入错误,请重新输入:");
break;
}
} while (input);
}
//删除联系人
void DeleteContact(Contact* pc)
{
assert(pc);
//如果已经空了提示后直接返回
if (pc->size == 0)
{
printf("通讯录已空,无法删除\n");
return;
}
printf("请输入你要删除的联系人:");
char name[NAME_MAX] = { 0 };
scanf("%s", name);
//先找到联系人
int pos = FindByName(pc,name);
if (pos == -1)
{
printf("联系人不存在\n");
return;
}
//如果存在 直接让pos位置后面的向前挪动 那么就覆盖了 实现删除效果
for (int i = pos; i < pc->size-1; i++)
{
pc->data[i] = pc->data[i + 1];
}
//别忘了size--
pc->size--;
printf("删除成功\n");
}
//根据名字排序
int cmp_by_name(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
//根据性别排序
int cmp_by_sex(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->sex, ((PeoInfo*)e2)->sex);
}
//根据年龄排序
int cmp_by_age(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
//电话排序
int cmp_by_tele(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->tele, ((PeoInfo*)e2)->tele);
}
//地址排序
int cmp_by_addr(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->addr, ((PeoInfo*)e2)->addr);
}
void SortContact(Contact* pc)
{
int input = 1;
//利用函数指针数组 代替switch语句
int(*p[6])(const void* e1, const void* e2) = { 0,cmp_by_name,cmp_by_age,cmp_by_sex,cmp_by_tele,cmp_by_addr };
while (input)
{
printf("**************************************\n");
printf("********** 1.name 2.age **********\n");
printf("********** 3.sex 4.tele **********\n");
printf("********** 5.addr 0.exit **********\n");
printf("**************************************\n");
printf("请选择你要按什么排序:>");
scanf("%d", &input);
if (0 == input)
{
printf("已退出\n");
break;
}
if (input > 0 && input <= 5)
{
qsort(pc->data, pc->size, sizeof(PeoInfo), *p[input]);
printf("排序成功\n");
break;
}
else {
printf("输入错误,请重新输入:>");
}
}
}
//清除
void ClearContact(Contact* pc)
{
//直接用memset置0
memset(pc->data, 0, MAX);
pc->size = 0;
printf("已清空\n");
}