【C语言进阶】 C语言实现简易通讯录

目录

 

普通版

功能需求

模块设计 

test.c模块实现 

contact.h模块实现

类型的声明

函数的声明

头文件、枚举、宏定义

contact.c 模块实现

初始化通讯录

增加联系人

显示所有联系人的信息

 查找函数 

删除指定联系人

查找指定联系人 

修改指定联系人

 进阶版通讯录(动态存储)

模块一test.c

模块二Contact.h

模块三Contact.c


 

普通版

功能需求

实现通讯录的增加、删除、查找、修改、显示 

2a59393af1884507b8a6ff7523de70ba.png

模块设计 

分为三个模块

test.c      测试通讯录

contact.h     函数和类型的声明

contact.c     函数的实现

test.c模块实现 

首先我们得有我们的主函数

int main()
{
	test();
	return 0;
}

然后我们在实现test函数时,我们需要完成通讯录的显示菜单,还需要操作者可以进行选择

527e6bc385094d93a939157612a20ad6.png

 具体实现如下

void menu()
{
	printf("***********      通讯录     *************\n");
	printf("******* 1 添加联系人  2 删除联系人 ******\n");
	printf("******* 3 查找联系人  4 修改联系人 ******\n");
	printf("******* 5 显示通讯录  0 退出通讯录 ******\n");
	printf("*****************************************\n");
}

void test()
{
	int input = 0;
	Contact con;//创建通讯录
	InitContact(&con);
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case ADD :
			AddContact(&con);
			break;
		case DEL :
			DelContact(&con);
			break;
		case SEARCH :
			SearchContact(&con);
			break;
		case MODIFY :
			ModifyContact(&con);
			break;
		case SHOW :
			ShowContact(&con);
			break;
		case EXIT :
			printf("退出通讯录\n");
			break;
		default: printf("输入错误,重新输入\n");
			break;
		}
	} while (input);
	
}

而在此处出现的结构体Contact与枚举会在contact.h模块进行声明,还有函数InitContact声明也会在contact.h说明,具体实现会在contact.c模块进行实现

contact.h模块实现

类型的声明


//类型的声明

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;

sz存在的意义为可以知道通讯录里有多少联系人

函数的声明

//函数声明

//初始化通讯录
void InitContact(Contact* pc);

//增加联系人
void AddContact(Contact* pc);

//显示所有联系人的信息
void ShowContact(const Contact* pc);

//删除指定联系人
void DelContact(Contact* pc);

//查找指定联系人
void SearchContact(const Contact* pc);

//修改指定联系人
void ModifyContact(Contact* pc);

头文件、枚举、宏定义

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
enum OPTION//枚举
{
	EXIT,//0
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW
};

contact.c 模块实现

初始化通讯录

void InitContact(Contact* pc)
{
	assert(pc);//断言,防止pc为空指针
	memset(pc->data, 0, sizeof(pc->data));//进行复制,每个字节都为0
	pc->sz = 0;
}

增加联系人

这里注意我们需要我们需要进行判断如果通讯录已满,我们就得进行提醒

void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->sz >= MAX)
	{
		printf("通讯录已满,无法添加");
		return;
	}
	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(const Contact* pc)
{
	assert(pc);
	int i = 0;
	//打印列标题
	printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
	//打印数据
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s\t%-4d\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(const Contact* pc, char name[])
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;//找到了
		}
	}
	return -1;//找不到
}

删除指定联系人

这里的删除其实是后面的数据对前面的数据的覆盖

52525990a2584407ac8051c88d84e36b.png

实现如下

void DelContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	char name[MAX_NAME] = { 0 };
	assert(pc);
	//删除
	printf("请输入要删除的人名字:>");
	scanf("%s", name);

	//找到要删除的人
	int del = FindByName(pc, name);
	if (del == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	int i = 0;
	//删除坐标位del的联系人
	for (i = del; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;

	printf("成功删除联系人\n");
}

查找指定联系人 

只需要按名字进行查找,最后进行输出就好,实现如下

void SearchContact(const Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法查找\n");
		return;
	}
	char name[MAX_NAME] = { 0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
		printf("要查找的人不存在\n");
	else
	{
		printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
		//打印数据
		printf("%-10s\t%-4d\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);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法修改\n");
		return;
	}
	char name[MAX_NAME] = { 0 };
	printf("请输入要修改人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
		printf("要修改的人不存在\n");
	else
	{
		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");
	}
}

 进阶版通讯录(动态存储)

进阶版通讯录实现与普通版通讯录区别在于,普通版通讯录的存储是有限,是提前规定好的,而进阶版则是可以根据用户的实际需求进行扩容。具体实现同样分为三个模块

模块一test.c

此模块没有什么变化

#include "Contact.h"

void menu()
{
	printf("***********      通讯录     *************\n");
	printf("******* 1 添加联系人  2 删除联系人 ******\n");
	printf("******* 3 查找联系人  4 修改联系人 ******\n");
	printf("******* 5 显示通讯录  0 退出通讯录 ******\n");
	printf("*****************************************\n");
}

void test()
{
	int input = 0;
	Contact con;//创建通讯录
	InitContact(&con);
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case ADD :
			AddContact(&con);
			break;
		case DEL :
			DelContact(&con);
			break;
		case SEARCH :
			SearchContact(&con);
			break;
		case MODIFY :
			ModifyContact(&con);
			break;
		case SHOW :
			ShowContact(&con);
			break;
		case EXIT :
			printf("退出通讯录\n");
			break;
		default: printf("输入错误,重新输入\n");
			break;
		}
	} while (input);
	
}

int main()
{
	test();
	return 0;
}

模块二Contact.h

由于变为了动态存储所以这里的结构的声明有一些变化

#include <stdlib.h>

#include <string.h>
#include <assert.h>
#include <stdio.h>


#define DEFAULT_SZ 3
#define INC_SZ 2
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30

enum OPTION//枚举
{
	EXIT,//0
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW
};


//类型的声明

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;//指向了存放数据的空间
	int sz;//记录的当前放的有效元素的个数
	int capacity;//通讯录当前的最大容量
}Contact;
//函数声明

//初始化通讯录
void InitContact(Contact* pc);

//增加联系人
void AddContact(Contact* pc);

//显示所有联系人的信息
void ShowContact(const Contact* pc);

//删除指定联系人
void DelContact(Contact* pc);

//查找指定联系人
void SearchContact(const Contact* pc);

//修改指定联系人
void ModifyContact(Contact* pc);

模块三Contact.c

修改如下

//静态版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	memset(pc->data, 0, sizeof(pc->data));
//	pc->sz = 0;
//}

//动态的版本
void InitContact(Contact* pc)
{
	assert(pc);
	memset(pc->data, 0, sizeof(pc->data));
	pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
}

//静态版本
//
//void AddContact(Contact* pc)
//{
//	assert(pc);
//	if (pc->sz == MAX)
//	{
//		printf("通讯录已满,无法添加\n");
//		return;
//	}
//
//	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");
//}

int CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ)*sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("CheckCapacity");
			return 0;
		}
		else
		{
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("增容成功\n");
			return 1;
		}
	}
	return 1;
}

//动态的版本
void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == MAX)

	if (0 == CheckCapacity(pc))
	{
		printf("通讯录已满,无法添加\n");
		return;
	}

    void AddContact(Contact* pc)
	printf("成功增加联系人\n");
}


void ShowContact(const Contact* pc)
{
	assert(pc);
    void ModifyContact(Contact* pc)
	}
}

//释放空间
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}

若有需要完整版的宝子或者在使用时出现了一些问题,都可以评论区评论或私信博主!!!

 

  • 25
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

遇事问春风乄

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

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

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

打赏作者

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

抵扣说明:

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

余额充值