【C语言】------- 模拟实现 [通讯录](详解)

前言

大家好,我是Abert。这篇文章和大家分享一个C语言小项目——通讯录,通讯录在我们日常生活中的使用也特别广泛,下面我们一起学习通讯录的实现吧!!!

文章目录

一.环境的配置

二.变量的创建

三.整体结构与功能的实现

        3.1 菜单

        3.2 新增联系人

        3.3 删除联系人

        3.4 查找联系人

        3.5 修改联系人

        3.6 显示联系人

        3.7 按姓名排序联系人

四.完整代码

        4.1 contact.h

        4.2 contact.c

        4.3 test.c

正文 

一.环境的配置

通讯录功能的实现需要创建一个头文件contact.h和两个源文件contact.c  、test.c

其中contact.h存放整个项目中需要的头文件以及contact.c中所用函数的声明

contact.c存放实现通讯录功能的代码

test.c存放主函数、菜单以及测试通讯录功能的代码,是整个项目的主体结构

contact.h被contact.c和test.c调用,contact.c被test.c调用


二.变量的创建 

创建一个结构体存放联系人的信息

联系人的基本信息:

姓名 性别 年龄 电话号码 地址

//类型的声明
#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;//重命名为PeoInfo

在创建一个结构体动态管理空间

动态开辟内存的好处是可以高效利用空间

//动态
typedef struct Contact
{
	PeoInfo* data;//可以存放信息
	int sz;//记录通讯录中已经保存的信息个数
	int capacity;//记录通讯录当前的最大容量
}Contact;

定义一个枚举类型的变量对应下文中菜单的使用


//枚举
enum Option
{
	EXIT,//0
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};

初始化通讯录

//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = 0;
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));//开辟空间

	//判断
	if (pc->data == NULL)
	{
		perror("InitContact::malloc");
		return;
	}

	memset(pc->data, 0, pc->capacity * sizeof(PeoInfo));//初始化内容为0

}


 三.整体结构与功能的实现

        3.1菜单

                把菜单的实现放入test.c文件中实现

void menu()
{
	printf("*******************************\n");
	printf("****** 1.add     2.del     ****\n");
	printf("****** 3.search  4.modify ****\n");
	printf("****** 5.sort    6.print   ****\n");
	printf("****** 0.exit              ****\n");
	printf("*******************************\n");

}

//1.add 增
//2.del 删
//3.search 查
//4.modify 改
//5.sort 排序
//6.print 显示
//0.exit 退出

下面功能的实现放入contact.c文件中 

        3.2 新增联系人

void AddContact(Contact* pc)
{
	assert(pc);
	CheckContact(pc);

	//录入信息
	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");

}

        3.3 删除联系人

oid DelContact(Contact* pc)
{
	assert(pc);

	if (pc->sz)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	//删除
	//1.找到
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除的人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	
	//2.删除
	int j = 0;
	for (j = 0; j < pc->sz - 1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}

	pc->sz--;
	printf("删除成功\n");

}

        3.4 查找联系人

//查找指定联系人
void SearchContact(const Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找的人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要找的人不存在\n");
		return;
	}
	
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);
}

        3.5 修改联系人

//修改指定联系人的信息
void ModifyContact(Contact* pc)
{
	assert(pc);

	char name[NAME_MAX];
	printf("请输入要修改的联系人的姓名:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);

	if (pos == -1)
	{
		printf("要修改的联系人不存在\n");
		return;
	}

	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");
}

         3.6 显示联系人

//打印通讯录
void PrintContact(const Contact* pc)
{
	assert(pc);

	int i = 0;
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");

	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
	}

}

        3.7 按姓名排序联系人

//按姓名排序通讯录
void SortContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("该通讯录中没有联系人信息,请添加\n");
		return;
	}

	//排序
	int i = 0;
	int j = 0;
	for (i = 0; i < pc->sz - 1; i++)
	{
		for (j = 0; j < pc->sz - i - 1; j++)
		{
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)//判断大小
			{
				PeoInfo tmp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = tmp;
			}
		}
	}
	printf("排序成功\n");
}

排序的方法和之前的冒泡排序类似,可以参考我之前的博客,哈哈。

注意:上面功能的实现均涉及空指针的判断!!!

                assert(pc) 与 assert(pc != NULL) 效果相同,若pc为空指针,程序将报错,方便后期调试排错。


四.完整代码.

        4.1 comtact.h

#pragma once
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

//类型的声明
#define MAX 1000

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30


//枚举
enum Option
{
	EXIT,//0
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};


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;//可以存放信息
	int sz;//记录通讯录中已经保存的信息个数
	int capacity;//记录通讯录当前的最大容量
}Contact;

//函数的声明

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

//检查通讯录空间
void CheckContact(Contact* pc);

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

//打印通讯录
void PrintContact(const Contact* pc);

//销毁通讯录
void DestroyContact(Contact* pc);

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

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

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

//按姓名排序通讯录
void SortContact(Contact* pc);

        4.2 contact.c

#include"contact.h"

//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = 0;
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));//开辟空间

	//判断
	if (pc->data == NULL)
	{
		perror("InitContact::malloc");
		return;
	}

	memset(pc->data, 0, pc->capacity * sizeof(PeoInfo));//初始化内容为0

}


//检查通讯录空间
void CheckContact(Contact* pc)
{
	//增容
	if (pc->sz == pc->capacity)
	{
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (tmp != NULL)
		{
			pc->data = tmp;
		}
		else
		{
			perror("CheckContact::realloc");
			return;
		}
		pc->capacity += 2;
		printf("增容成功\n");
	}

}


//增加联系人的信息
void AddContact(Contact* pc)
{
	assert(pc);
	CheckContact(pc);

	//录入信息
	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 PrintContact(const Contact* pc)
{
	assert(pc);

	int i = 0;
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");

	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
	}

}


//销毁通讯录
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	printf("销毁成功\n");

}


int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (0 == strcmp(pc->data[i].name, name))
		{
			return i;//找到了返回下标
		}
	}
	return -1;//找不到返回-1
}


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

	if (pc->sz)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	//删除
	//1.找到
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除的人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	
	//2.删除
	int j = 0;
	for (j = 0; j < pc->sz - 1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}

	pc->sz--;
	printf("删除成功\n");

}


//查找指定联系人
void SearchContact(const Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找的人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要找的人不存在\n");
		return;
	}
	
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-20s %-5d %-5s %-12s %-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[NAME_MAX];
	printf("请输入要修改的联系人的姓名:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);

	if (pos == -1)
	{
		printf("要修改的联系人不存在\n");
		return;
	}

	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");
}


//按姓名排序通讯录
void SortContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("该通讯录中没有联系人信息,请添加\n");
		return;
	}

	//排序
	int i = 0;
	int j = 0;
	for (i = 0; i < pc->sz - 1; i++)
	{
		for (j = 0; j < pc->sz - i - 1; j++)
		{
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)//判断大小
			{
				PeoInfo tmp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = tmp;
			}
		}
	}
	printf("排序成功\n");
}

        4.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"

void menu()
{
	printf("*******************************\n");
	printf("****** 1.add     2.del     ****\n");
	printf("****** 3.search  4.modify ****\n");
	printf("****** 5.sort    6.print   ****\n");
	printf("****** 0.exit              ****\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 SORT:
			SortContact(&con);
			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT:
			DestroyContact(&con);
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}

	} while (input);


}


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

总结

        通讯录的实现用到的重要知识有:指针、结构体、动态内存管理。动态开辟内存的具体过程对于初学者不是特别好把握,可以通过多看多写加深理解。

通讯录实现出来大概试下面的样子

输入功能相对应的数字即可调用相应的功能 

下面举例:

添加一个联系人的信息(电话号码是随便写的)

阿尔伯特   男     20     15029055542    西安市

 然后在选择显示联系人的功能即可查看:

剩下的大家自己探索吧 哈哈哈

这篇文章的内容就是这些,欢迎大家学习交流。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值