C语言模拟实现(动态版通讯录)

1.模拟实现通讯录总体架构一览图

在这里插入图片描述

2.文件执行任务

在这里插入图片描述

3.分模块实现

测试模块 test.c

1.为了更好地展示,制作一个菜单,在菜单中有 添加,删除,查找,修改,排序,清空,退出的选项。
2.因为起先要进入程序一趟,所以用do····while循环(输入选项来看具体操作,退出还是其他操作)

 #include "contact.h"
void menu()
{

	printf("*****************************************\n");
	printf("********          Contact          ******\n");
	printf("********     1.add     2. del      ******\n");
	printf("********     3.search  4.modify    ******\n");
	printf("********     5.print   6.empty     ******\n");
	printf("********     7.sort    0.exit      ******\n");
	printf("*****************************************\n");

}
enum Option
//为什么要使用枚举
//因为这样可以防止命名污染,而且使用枚举,枚举成员有默认初始值,默认从0开始,这样省去的诸多的代码量
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	PRINT,
	EMPTY,
	SORT,
};
int main()
{
	//先打印菜单,展示通讯录功能
	int input = 0;
	//先进行设置一个通讯录
	//设置每个人的信息
	//初始化通讯录 
	//通讯录中的一个元素
	contact con; 
	//contact 是自定义数据类型,包括一个联系人的基本信息
	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 PRINT:
			//显示
			PrintContact(&con);
			break;
		case SORT:
			//实现名字排序
			SortContact(&con);
			break;
		case EMPTY:
			//实现清空
			EmptyContact(&con);
			break;
		case EXIT:
			//退出程序
			ExitContact(&con);
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	} while (input);
	return 0;
}

头文件 功能函数声明 contact.h

1.声明各类功能函数
2.定义各个常量,把常量定义成通俗易懂的变量,便于在多处使用。
3.定义结构体,自定义类型中,有一个联系人的基本信息。

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_NAME 20 //定义姓名字符串的大小为20
#define MAX_SEX 10 //定义性别字符串的大小为10
#define MAX_TELE 12 //定义电话字符串的大小为12
#define MAX_ADDR 20 //定义地址字符串的大小为20
#define MAX 1000  //定义通讯录的最大容量为1000
#define IN_NUM 3  //在动态申请空间时默认空间为3
#define SET_NUM 2  //当基本信息大于3份时,开辟两个空间
//设置每一个人的信息
//通讯录规定要求一共有1000个人
typedef struct base
{
	char name[MAX_NAME]; //姓名
	char sex[MAX_SEX];   //性别
	int age;             //年龄
	char tele[MAX_TELE]; //电话
	char addr[MAX_ADDR]; //住址
}base;
//设置1000人的通讯录
//静态版
//typedef struct contact
//{
//	 
//	int sz;           //计算当前通讯录中联系人的个数
//	base data[MAX]; //存放联系人的信息
// 
//}contact;
//动态初始化通讯录
typedef struct contact
{
	//有个结构体类型中需要,监视通讯录人数的一项,还有当联系人为3人时,这时候要进行增容
	int sz;   //计算当前联系人的个数
	base* data; //指向动态申请的空间,存放联系人的信息
	int capciaty; //计算当前通讯录中的最大容量
}contact;

//初始化通讯录
void InitContact(contact* pc);
//添加联系人
void AddContact(contact* pc);
//显示
void PrintContact(contact* pc);
//删除联系人
void DelContact(contact* pc);
//查找联系人
void SearchContact(contact* pc);
//修改信息
void ModifyContact(contact* pc);
//排序联系人信息
void SortContact(contact* pc);
//清空联系人信息
void EmptyContact(contact* pc);
//退出程序时,释放空间
void ExitContact(contact* pc);

功能函数逐一实现 contact.c

1.初始化通讯录

动态申请空间
默认在动态空间中存放3个基本单位信息

 void InitContact(contact* pc)
{

	pc->data = (base*)malloc(sizeof(base) * IN_NUM);

	if (pc->data == NULL)
	//如果空间开辟失败
	//退出程序
	{
		perror("InitContact");
		return;
	}
	//把每个成员都设置为0
	pc->sz = 0;
 
	pc->capciaty = IN_NUM;
}
2.添加联系人

当默认的空间被装满时,然后以后的每一次都开辟两个基本空间

void AddContact(contact* pc)
{
//先判断通讯录中是否满了
	//if (pc->sz == MAX)
	//{
	//	printf("通讯录已满,无法添加\n");
	//	return;
	//}
	//动态判断人的个数是否满足3
	if (pc->sz == pc->capciaty)
	{
		printf("开始增容:\n");
		//从新设置一个指针,存放新开辟的内存
		base* ptr = (base*)realloc(pc->data, (pc->capciaty + SET_NUM) * sizeof(base));
		//判断是否开辟成功
		if (ptr == NULL)
		{
			printf("开辟失败\n");
			perror("AddContact");
			return;
		}
		else
		{
			printf("开辟成功\n");
			//开辟成功的话,把ptr转交给data来维护,这样在内存释放的时候只需要释放pc->data
			pc->data = ptr;
			//增加基本信息数量
			pc->capciaty += SET_NUM;
		}
		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");
}
3.显示联系人信息

逐一打印联系人信息,注意之间的距离(保持美观)

 //显示
void PrintContact(contact* pc)
{
	//显示标题
	printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s %-10s %-5d %-15s %-20s\n", 
		    pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].age,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}
4.删除联系人

在删除联系人之前,首先要查找要删除联系人的名字,然后进行删除,注意如何删除
让删除的这个单位的后一个单位去覆盖这个删除的单位(这样原来要删除的地方变成了后面一个值) i = i+1
当通讯录中有被删除着的名字时,返回这个单位的下标
当通讯录中没有时,返回-1

 //查找联系人
static int Find_name(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;
}
//删除联系人
void DelContact(contact* pc)
{
	//如果通讯录是空的
	if (pc->sz == 0)
	{
		printf("通讯为空,无需删除\n");
		return;
	}
//下进行查找被删除联系人的名字
	char name[MAX_NAME];
	printf("请输入要删除联系人的名字:");
	scanf("%s", name);
	int ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("该联系人不存在\n");
		return;
	}
	//删除
	//删除项后边的一项,覆盖前面的一项
	for (int i = ret; i < pc->sz; 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 ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("该联系人不存在\n");
		return;
	}
	printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址");
	printf("%-20s %-10s %-5d %-15s %-20s\n", pc->data[ret].name,
			pc->data[ret].sex,
			pc->data[ret].age,
			pc->data[ret].tele,
			pc->data[ret].addr);
}
5.修该联系人信息

还是现在通讯录中查找这个联系人,在进行输入修改

 //修改信息
void ModifyContact(contact* pc)
{
	char name[MAX_NAME];
	printf("请输入要修改联系人的名字:");
	scanf("%s", name);
	int ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("该联系人不存在\n");
		return;
	}
	printf("姓名是>");
	scanf("%s", pc->data[ret].name);
	printf("年龄是>");
	scanf("%d", &pc->data[ret].age);
	printf("性别>");
	scanf("%s", pc->data[ret].sex);
	printf("电话>");
	scanf("%s", pc->data[ret].tele);
	printf("住址>");
	scanf("%s", pc->data[ret].addr);
}
6.排序联系人姓名

利用冒泡排序对联系人的名字进行排序(也可以使用快排)

 //排序
//交换名字,但是名字要和联系人的信息匹配
//先比较名字,根据名字的大小,再排序
static void SwapByname(base* pa, base* pb)
{
	base b;
	b = *pa;
	*pa = *pb;
	*pb = b;
}
void SortContact(contact* pc)
{
	printf("开始排序\n");
  //使用冒泡排序对联系人的名字进行排序
	int i = 0;
	int j = 0;
	for (i = 0; i < pc->sz; i++)
	{
		for (j = 0; j < pc-> sz - i - 1; j++)
		{
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
			{
				 //实现交换姓名
				SwapByname(&pc->data[j], &pc->data[j + 1]);
			}
		}
	}
	printf("排序结束\n");
}
7.清空联系人

在这里直接使用sz–,就可以删除

 //清空
void EmptyContact(contact* pc)
{
//如果原来的通讯录是空的就无须清空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需清空\n");
		return;
	}
	 
	printf("开始清除数据:\n");
	int num = pc->sz;
	for (int i = 0; i < num; i++)
	{
		pc->sz--;
	}
	printf("清空完毕\n");
}
8.退出通讯录

手动开辟,手动释放

 //退出程序,释放空间
void ExitContact(contact* pc)
{
	//释放空间
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capciaty = 0;
}

运行展示:
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
一、题目:通讯录管理 二、目的与要求 1. 目的: (1)基本掌握面向过程程序设计的基本思路和方法; (2)达到熟练掌握C语言的基本知识和技能; (3)能够利用所学的基本知识和技能,解决简单的程序设计问题 2. 要求 基本要求: 1. 要求利用C语言面向过程的编程思想来完成系统的设计; 2. 突出C语言的函数特征,以多个函数实现每一个子功能; 3. 画出功能模块图; 4. 具有清晰的程序流程图和数据结构的详细定义; 5. 熟练掌握C语言对文件的各种操作。 创新要求: 在基本要求达到后,可进行创新设计,如系统用户功能控制,对管理员级和一般级别的用户系统功能操作不同 三、信息描述 有关该系统基本信息的描述,如:姓名、电话、城市和邮编等。 四、功能描述 1. 名单基本信息(姓名,城市,电话,邮编等)的录入,并存放在文件当中。 2. 基本信息的查询与修改。 3. 记录的添加和删除。 4. 对同一类型记录的查找:如查找同一城市的记录或同一省份的记录。 五、解决方案 1. 分析程序的功能要求,划分程序功能模块。 2. 画出系统流程图。 3. 代码的编写。定义数据结构和各个功能子函数。 4. 程序的功能调试。 5. 完成系统总结报告以及使用说明书 六、进度安排 此次课程设计时间为一周或两周,分四个阶段完成: 1. 分析设计阶段。指导教师应积极引导学生自主学习和钻研问题,明确设计要求,找出实现方法,按照需求分析、总体设计、详细设计这几个步骤进行。 2. 编码调试阶段:根据设计分析方案编写C代码,然后调试该代码,实现课题要求的功能。 3. 总结报告阶段:总结设计工作,写出课程设计说明书,要求学生写出需求分析、总体设计、详细设计、编码、测试的步骤和内容。 4. 考核阶段。 七、撰写课程设计报告或课程设计总结 课程设计报告要求: 总结报告包括需求分析、总体设计、详细设计、编码(详细写出编程步骤)、测试的步骤和内容、课程设计总结、参考资料等,不符合以上要求者,则本次设计以不及格记。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小周学编程~~~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值