C语言实现通讯录----(静态版本)

✨ 写在前面

🎃 哈喽 大家好👋👋👋
🌱 作为一个初入编程的大学生,知识浅薄,但还是要学习大佬写一下前言滴(🤭)
🌱 我的其他文章
       1.【C语言】字符串函数使用+模拟【上】
       2.【C语言】彻底搞明白C语言一大关卡—C指针【初阶】
       3.【C语言】字符串操作函数&&字符串查找&&内存操作函数【下】

🌱 初入编程的世界 前方"路漫漫"🛣️ 每天我们都要进步一点点💧
🌱 希望分享知识的同时可以和你们一起进步🍻

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

⭐⭐这里是目录⭐⭐

 📜1.准备工作

📜2. 定义结构体

 📜3. 明确好我们想要实现的功能:

📜4.根据功能把菜单写好,这里和之前的三子棋逻辑差不多

📜5.实现各功能函数

🏷️5.1 通讯录初始化

 🏷️5.2 通讯录增加联系人

🏷️ 5.3 通讯录打印

🏷️5.4 查找联系人

 🏷️5.5 修改联系人

​🔖 5.5.1 修改姓名(同修改性别,电话,地址)

🔖5.5.2 修改年龄

 🏷️5.6 删除联系人

 🏷️5.7 排序

🏷️5.8 清除

📜6.总代码

📇1.contact.h

📇2.test.c

📇3.contact.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");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2021狮子歌歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值