[C进阶]静态通讯录的实现

前言

在上一次我们学习了有关自定义类型中的所有知识,今天我们就来尝试一下实现一个静态的通讯录,后续我也会与大家分享动态通讯录的实现,大家不要迷路哦

一.开始

这一次我们需要创建三个文件来进行静态通讯录的实现,我们将在contact.h头文件中进行函数的定义,在contact.c文件中进行函数的实现,在test.c文件中实现我们的通讯录

在这里插入图片描述

1.通讯录的功能

首先我们要知道通讯录中存放的数据都有哪些和通讯录的功能。

一般一个通讯录中有联系人的名字,年龄,性别,电话和地址。通讯录可以增加,减少,查找,删除联系人,修改联系人信息,展示联系人信息。
知道这些后我们就可以开干了。

2.创建结构体

我们首先在头文件中创建一个结构体来存放联系人的不同信息
在这里插入图片描述

在后期如果我们想修改结构体中每个类型的大小会比较麻烦,所以我们可以用 #define来定义每个变量的大小,这样我们在后面想要改变结构体变量大小是可以直接改变 #define 的大小就可以改变所以的变量大小了。

在这里插入图片描述

同时我们想知道通讯录中有多少联系人,可以再创建一个结构体把联系人信息和联系人个数一起包含进去,这样可以更加的方便。

在这里插入图片描述

3.test.c整体逻辑

  • 打印菜单
    首先我们要定义一个manu函数来打印菜单,在我们实现整个函数时可以通过菜单选择我们要进行的操作

首先我们就要创建一个contact类型的变量,并把这个变量初始化为0.

void initcontact(contact* pc)
{
    
    
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

int main()
{
    
    
    contact con;
	initcontact(&con);
}

后面我们想不断测试我们的函数,所以我们可以使用do-while循环,并选择switch case语句来实现我们的每一步操作

	do
	{
    
    
		manu();
		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:
			break;
		default:
			break;
		}
	} while (input);

我们在写代码的时候想知道case 1,2,3代表的意思时还需要上下翻看,所以我们可以通过枚举的方法将case后的数字变成我们的枚举变量,这样我们就能一眼看出来我们将要写的内容是什么了。

我们每选择一个操作,switch语句便会执行相应的函数

enum option
{
    
    
	EXIT,
	ADD,
	SHOW,
	DEL,
	SEARCH,
	MODIFY,
	SORT
};
	do
	{
    
    
		manu();
		printf("请选择一个数->");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case ADD:
			addcontact(&con);
			printf("\n输入完毕\n");
			break;
		case SHOW:
			showcontact(&con);
			break;
		case DEL:
			delcontact(&con);
			printf("\n删除完毕\n");
			break;
		case SEARCH:
			searchcontact(&con);
			break;
		case MODIFY:
			modifycontact(&con);
			printf("修改完毕\n");
			break;
		case SORT:
			sortcontact(&con);
			printf("排序成功\n");
			break;
		case EXIT:
			printf("退出\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (input);

二.函数的实现

1.添加联系人

我们想要添加联系人时需要判断通讯录是不是已经满了,如果没满,我们将输入联系人的信息。如果满了,我们就退出程序

void addcontact(contact* pc)
{
    
    
	if (MAX == pc->sz)
	{
    
    
		printf("通讯录已满,无法增加\n");
		return;
	}
	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");
}

测试一下,这样就添加成功了
在这里插入图片描述

2.展示联系人信息

我们可以通过循环来打印出每个人的信息,在printf中加入数字可以左右对齐,使我们打印的更美观

void showcontact(contact* pc)
{
    
    
	int i = 0;
	printf("%-8s%-8s%-8s%-15s%-15s\n", "名字", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pc->sz; i++)
	{
    
    
		printf("%-8s", pc->data[i].name);
		printf("%-8d", pc->data[i].age);
		printf("%-8s", pc->data[i].sex);
		printf("%-15s", pc->data[i].tele);
		printf("%-15s\n", pc->data[i].addr);
	}
}

在这里插入图片描述

3.删除联系人

首先我们要判断通讯录是否为空,若不为空,找到联系人时,我们可以通过覆盖的方式删除联系人,联系人数量减一。若找不到,则退出通讯录。

我们可以构建一个find函数来寻找联系人


int find_by_name(contact*pc ,char name[])
{
    
    
	int i;
	for (i = 0; i < pc->sz; i++)
	{
    
    
		if (0 == strcmp(name, pc->data[i].name))
		{
    
    
			return i;
		}
	}
	return -1;
}

接下来我们就可以删除联系人了

char name[MAX];
if (pc->sz == 0)
	{
    
    
		printf("通讯录为空,无法删除\n");
		return;
	}
	//删除
	//1. 找到要删除的人 - 位置(下标)
	printf("输入要删除人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
    
    
		printf("要删除的人不存在\n");
		return;
	}
	int i = 0;
	//2. 删除 - 删除pos位置上的数据
	for (i = pos; i<pc->sz-1; 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 pos = find_by_name(pc, name);
	if (-1 == pos)
	{
    
    
		printf("此人不存在\n");
	}
	printf("%-8s%-8s%-8s%-15s%-15s\n", "名字", "年龄", "性别", "电话", "地址");
	printf("%-8s", pc->data[pos].name);
	printf("%-8d", pc->data[pos].age);
	printf("%-8s", pc->data[pos].sex);
	printf("%-15s", pc->data[pos].tele);
	printf("%-15s\n", pc->data[pos].addr);
}

5.修改联系人信息

同样的,我们只需要找到联系人,然后把他的信息重新输入一遍即可

void modifycontact(contact* pc)
{
    
    
	char name[MAX_NAME];
	printf("请输入要修改的人->");
	scanf("%s", name);
	int pos = find_by_name(pc, name);
	if (-1 == pos)
	{
    
    
		printf("此人不存在\n");
	}
	printf("请输入联系人信息\n");
	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);
}

在这里插入图片描述

6.进行排序

我们想进行排序可以使用qsort函数来实现不同种排序方法
在这里插入图片描述


int cmp_by_name(const void* p1, const void* p2)
{
    
    
	return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}
int cmp_by_age(const void* p1, const void* p2)
{
    
    
	return strcmp(((peoinfo*)p1)->age, ((peoinfo*)p2)->age);
}
void sortcontact(contact* pc)
{
    
    
	qsort(pc->data, pc->sz, sizeof(peoinfo), cmp_by_name);
}

在这里插入图片描述

三.整体代码

1.comtact.h代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 15
#define MAX_ADDR 30
#define MAX 100
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 sz;
}contact;
//初始化通讯录
void initcontact(contact* pc);
 
void addcontact(contact* pc);

void showcontact(contact* pc);

void delcontact(contact* pc);

void searchcontact(contact* pc);

void modifycontact(contact* pc);

void sortcontact(contact* pc);

2.coatact.c代码

#include "contact.h"
void initcontact(contact* pc)
{
    
    
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

void addcontact(contact* pc)
{
    
    
	if (MAX == pc->sz)
	{
    
    
		printf("通讯录已满,无法增加\n");
		return;
	}
	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");
}

void showcontact(contact* pc)
{
    
    
	int i = 0;
	printf("%-8s%-8s%-8s%-15s%-15s\n", "名字", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pc->sz; i++)
	{
    
    
		printf("%-8s", pc->data[i].name);
		printf("%-8d", pc->data[i].age);
		printf("%-8s", pc->data[i].sex);
		printf("%-15s", pc->data[i].tele);
		printf("%-15s\n", pc->data[i].addr);
	}
}

int find_by_name(contact*pc ,char name[])
{
    
    
	int i;
	for (i = 0; i < pc->sz; i++)
	{
    
    
		if (0 == strcmp(name, pc->data[i].name))
		{
    
    
			return i;
		}
	}
	return -1;
}
void delcontact(contact* pc)
{
    
    
	char name[MAX];
	if (pc->sz == 0)
	{
    
    
		printf("通讯录为空,无法删除\n");
		return;
	}
	//删除
	//1. 找到要删除的人 - 位置(下标)
	printf("输入要删除人的名字:>");
	scanf("%s", name);
	int pos = find_by_name(pc, name);
	if (pos == -1)
	{
    
    
		printf("要删除的人不存在\n");
		return;
	}
	int i = 0;
	//2. 删除 - 删除pos位置上的数据
	for (i = pos; i < pc->sz - 1; i++)
	{
    
    
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}

void searchcontact(contact* pc)
{
    
    
	char name[MAX_NAME];
	printf("请输入要查询的人->");
	scanf("%s", name);
	int pos = find_by_name(pc, name);
	if (-1 == pos)
	{
    
    
		printf("此人不存在\n");
	}
	printf("%-8s%-8s%-8s%-15s%-15s\n", "名字", "年龄", "性别", "电话", "地址");
	printf("%-8s", pc->data[pos].name);
	printf("%-8d", pc->data[pos].age);
	printf("%-8s", pc->data[pos].sex);
	printf("%-15s", pc->data[pos].tele);
	printf("%-15s\n", pc->data[pos].addr);
}

void modifycontact(contact* pc)
{
    
    
	char name[MAX_NAME];
	printf("请输入要修改的人->");
	scanf("%s", name);
	int pos = find_by_name(pc, name);
	if (-1 == pos)
	{
    
    
		printf("此人不存在\n");
	}
	printf("请输入联系人信息\n");
	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);
}

int cmp_by_name(const void* p1, const void* p2)
{
    
    
	return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}
int cmp_by_age(const void* p1, const void* p2)
{
    
    
	return strcmp(((peoinfo*)p1)->age, ((peoinfo*)p2)->age);
}
void sortcontact(contact* pc)
{
    
    
	qsort(pc->data, pc->sz, sizeof(peoinfo), cmp_by_name);
}

3.test.c代码

#include "contact.h"
void manu()
{
    
    
	printf("****************************************\n");
	printf("****************************************\n");
	printf("*******  1.add        2.show    ********\n");
	printf("*******  3.del        4.search  ********\n");
    printf("*******  5.modify     6.sort    ********\n");
    printf("*******  0.exit                 ********\n");
	printf("****************************************\n");
	printf("****************************************\n");
}
enum option
{
    
    
	EXIT,
	ADD,
	SHOW,
	DEL,
	SEARCH,
	MODIFY,
	SORT
};
int main()
{
    
    
	contact con;
	initcontact(&con);
	int input = 0;

	do
	{
    
    
		manu();
		printf("请选择一个数->");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case ADD:
			addcontact(&con);
			printf("\n输入完毕\n");
			break;
		case SHOW:
			showcontact(&con);
			break;
		case DEL:
			delcontact(&con);
			break;
		case SEARCH:
			searchcontact(&con);
			break;
		case MODIFY:
			modifycontact(&con);
			printf("修改完毕\n");
			break;
		case SORT:
			sortcontact(&con);
			printf("排序成功\n");
			break;
		case EXIT:
			printf("退出\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (input);
	return 0;
}

结尾

先赞后看,养成习惯!!^ _ ^
码字不易,大家的支持就是我坚持下去的动力,点赞后不要忘了关注我哦!

如有错误,还请您批评改正(。ì _ í。)

猜你喜欢

转载自blog.csdn.net/qq_65673848/article/details/129770098