【C语言实战项目】通讯录(动态增容版)

这篇具有很好参考价值的文章主要介绍了【C语言实战项目】通讯录(动态增容版)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🦄个人主页:修修修也

🎏所属专栏:数据结构

⚙️操作环境:Visual Studio 2022

【C语言实战项目】通讯录(动态增容版),c语言,开发语言


目录

一.动态增容版简介

二.动态增容版逐步实现详解

1.创建通讯录

2. 初始化通讯录

3.增加联系人

4.通讯录增容

5.销毁通讯录

三.动态增容版代码整合

contact.c

test.c

contact.h


一.动态增容版简介

上篇博客我们一起用C语言实现了一个固定大小的通讯录程序,这篇博客里我们将借助动态内存相关知识把他改造成可以动态增加大小的版本.

二.动态增容版逐步实现详解

1.创建通讯录

创建部分与静态版不同的是,因为我们在通讯录成员个数扩容的时候需要有一个变量来记录当前通讯录的最大容量,因此我们在结构体中多创建一个变量capacity用来记录当前通讯录的最大容量.

该部分代码如下:

//动态版本
#define DEFAULT_SZ 3
#define INC_SZ 2

//人的信息-结构体
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];//电话11位,留一位给'\0';
}PeoInfo;

//动态版本
typedef struct Contact
{
	PeoInfo* data;//存放人的信息
	int sz;//用来记录当前已经存放的信息的个数
	int capacity;//记录当前通讯录的最大容量
}Contact;

2. 初始化通讯录

初始化的部分我们可以将原来的初始化方法替换成使用calloc函数动态开辟通讯录的初始大小的同时进行初始化.

//初始化通讯录成员(动态版)
void InitContact(Contact* pc)
{
	assert(pc);

	pc->sz = 0;
	PeoInfo * ptr = (PeoInfo*)calloc(DEFAULT_SZ , sizeof(PeoInfo));

	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return;
	}

	pc->data = ptr;

	pc->capacity = DEFAULT_SZ;

}

3.增加联系人

增加联系人的部分则需要先判断通讯录当前是否满了,如果是,则转入扩容函数,如果不是则正常进行增加联系人操作.

//增加联系人(动态版)
void AddContact(Contact* pc)
{
	assert(pc);
	//检查是不是满了
	check_capacity(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].addr);

	printf("请输入电话;>");
	scanf("%s", pc->data[pc->sz].tele);

	//每次录入完,sz自增
	pc->sz++;
	printf("联系人添加成功:>\n");
}

4.通讯录增容

通讯录的增容部分使用realloc函数来实现,当然要记得检查realloc返回的指针是否为空,如果为空则要输出内容提醒程序员出错的原因.

void check_capacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		//增容
		PeoInfo*ptr=(PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity::realloc");
			return;
		}
		pc->data = ptr;
		pc->capacity += INC_SZ;

	}
}

5.销毁通讯录

销毁通讯录是动态内存开辟非常重要的一步,如果使用动态内存开辟后忘记销毁,就会造成内存泄漏.因此在程序结束退出时我们一定要记得使用free将前面动态开辟的空间释放掉.

//销毁通讯录
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	pc = NULL;
}

三.动态增容版代码整合

我们将程序运行的代码分为三个模块分开书写,完整代码如下:

contact.c

//contact.c通讯录的实现
#include"contact.h"

//初始化通讯录成员(动态版)
void InitContact(Contact* pc)
{
	assert(pc);

	pc->sz = 0;
	PeoInfo * ptr = (PeoInfo*)calloc(DEFAULT_SZ , sizeof(PeoInfo));

	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return;
	}

	pc->data = ptr;

	pc->capacity = DEFAULT_SZ;

}


//销毁通讯录
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	pc = NULL;
}


void check_capacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		//增容
		PeoInfo*ptr=(PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity::realloc");
			return;
		}
		pc->data = ptr;
		pc->capacity += INC_SZ;

	}
}


//增加联系人(动态版)
void AddContact(Contact* pc)
{
	assert(pc);
	//检查是不是满了
	check_capacity(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].addr);

	printf("请输入电话;>");
	scanf("%s", pc->data[pc->sz].tele);

	//每次录入完,sz自增
	pc->sz++;
	printf("联系人添加成功:>\n");
}

//按人名查找联系人
int FindByName(const Contact* pc, char* name)
{
	assert(pc);

	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)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	//防止通讯录删完了
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}

	//找到要删除的对象
	printf("请输入要删除的人的名字:>");
	scanf("%s", name);
	int del = FindByName(pc, name);


	if (-1 == del)
	{
		printf("抱歉,没有找到您要删除的对象;<\n");
		return;
	}
	int i = 0;
	//删除
	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);
	char name[NAME_MAX] = { 0 };
	//找到要查找的对象
	printf("请输入要查找的人的名字:>");
	scanf("%s", name);
	int sea = FindByName(pc, name);

	if (-1 == sea)
	{
		printf("抱歉,没有找到您要查找的对象;<\n");
		return;
	}

	//打印信息
	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");
	printf("________________________________________________________________________________________\n");
	printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n", sea + 1,
		pc->data[sea].name,
		pc->data[sea].age,
		pc->data[sea].sex,
		pc->data[sea].addr,
		pc->data[sea].tele);
	printf("________________________________________________________________________________________\n");
}


//修改联系人信息
void modifyContact(Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	//找到要修改的对象
	printf("请输入要修改的人的名字:>");
	scanf("%s", name);
	int mod = FindByName(pc, name);

	if (-1 == mod)
	{
		printf("抱歉,没有找到您要修改的对象;<\n");
		return;
	}
	printf("请输入修改后的联系人信息\n");
	printf("请输入名字;>");
	scanf("%s", pc->data[mod].name);

	printf("请输入年龄;>");
	scanf("%d", &(pc->data[mod].age));

	printf("请输入性别;>");
	scanf("%s", pc->data[mod].sex);

	printf("请输入地址;>");
	scanf("%s", pc->data[mod].addr);

	printf("请输入电话;>");
	scanf("%s", pc->data[mod].tele);

	printf("修改成功;>\n");

	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");
	printf("________________________________________________________________________________________\n");
	printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n", mod + 1,
		pc->data[mod].name,
		pc->data[mod].age,
		pc->data[mod].sex,
		pc->data[mod].addr,
		pc->data[mod].tele);
	printf("________________________________________________________________________________________\n");
}


//显示通讯录中的信息
void ShowContact(const Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法显示\n");
		return;
	}
	int i = 0;
	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("________________________________________________________________________________________\n");
		printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n", i + 1,
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);

	}
	printf("________________________________________________________________________________________\n");

}


//清空联系人信息
void EmptyContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需清空\n");
		return;
	}
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
	printf("清空成功:>\n");

}


//comper按姓名排序
int comper_name(const void* a, const void* b)
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->name, personB->name);
}
//comper按年龄排序
int comper_age(const void* a, const void* b)
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return (personA->age - personB->age);
}
//comper按性别排序
int comper_sex(const void* a, const void* b)
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->sex, personB->sex);
}
//comper按住处排序
int comper_addr(const void* a, const void* b)
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->addr, personB->addr);
}


//给联系人排序
void SortContact(Contact* pc)
{
	int cho = 0;
	if (pc->sz == 0)
	{
		printf("通讯录为空,请先加入联系人\n");
		return;
	}
	printf("******************************\n");
	printf("********   1.按姓名  *********\n");
	printf("********   2.按年龄  *********\n");
	printf("********   3.按性别  *********\n");
	printf("********   4.按地址  *********\n");
	printf("******************************\n");
	printf("请选择您想使用的排序方式:>");
	scanf("%d", &cho);

	int (*compare_func)(const void*, const void*) = NULL;

	switch (cho)
	{
	case 1:
		compare_func = comper_name;
		break;
	case 2:
		compare_func = comper_age;
		break;
	case 3:
		compare_func = comper_sex;
		break;
	case 4:
		compare_func = comper_addr;
		break;
	default:
		printf("排序选项无效:<\n");
		return;
	}

	// 使用qsort函数进行排序
	qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_func);

	printf("排序成功:>\n");

	ShowContact(pc);
}




test.c

//test.c测试通讯录

#include"contact.h"

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

int main()
{
	int input = 0;
	//创建通讯录
	Contact con;
	//初始化通讯录

	InitContact(&con);
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			searchContact(&con);
			break;
		case 4:
			modifyContact(&con);
			break;
		case 5:
			ShowContact(&con);
			break;
		case 6:
			EmptyContact(&con);
			break;
		case 7:
			SortContact(&con);
			break;
		case 0:
			DestroyContact(&con);
			printf("退出程序:>\n");
			break;
		default:
			printf("输入非法,请重新输入!\n");
			break;
		}
	} while (input);

	return 0;
}

contact.h

#pragma once
//contact.h函数的声明
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

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

//动态版本
#define DEFAULT_SZ 3
#define INC_SZ 2

//人的信息-结构体
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];//电话11位,留一位给'\0';
}PeoInfo;

//动态版本
typedef struct Contact
{
	PeoInfo* data;//存放1000个人的信息
	int sz;//用来记录当前已经存放的信息的个数
	int capacity;//记录当前通讯录的最大容量
}Contact;


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

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

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

//删除通讯录中的信息
void DelContact(Contact* pc);

//显示通讯录中的信息
void ShowContact(const Contact* pc);

//查找联系人并打印其信息
void searchContact(const Contact* pc);

//修改联系人信息
void modifyContact(Contact* pc);

//清空联系人信息(和初始化逻辑一模一样)
void EmptyContact(Contact* pc);

//给联系人排序
void SortContact(Contact* pc);

结语

希望这篇通讯录的动态增容实现详解能对大家有所帮助,欢迎大佬们留言或私信与我交流.

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!

相关文章推荐

【数据结构】线性表的顺序存储结构

【C语言】malloc()函数详解(动态内存开辟函数)

【C语言】free()函数详解(动态内存释放函数)

【C语言】calloc()函数详解(动态内存开辟函数)

【C语言】realloc()函数详解(动态内存开辟函数)

【C语言】memcpy()函数

【数据结构实战项目】C语言实现数据结构顺序表万字详解(附完整运行代码)


【C语言实战项目】通讯录(动态增容版),c语言,开发语言文章来源地址https://www.toymoban.com/news/detail-674346.html


到了这里,关于【C语言实战项目】通讯录(动态增容版)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态通讯录实现(C语言)

    目录 前言: 一:单个节点的设计和主逻辑  结点设计 主逻辑 二:接口实现 (1)生成一个新的结点 (2)增加信息 (3)打印信息 (4)查找  (5)删除信息 (6)修改信息 (7)排序  插入排序 快速排序 (8)已有数据读取 (9)更新数据录入 三:全部代码 contact.h(声明) contact.c(接口) test.c(主逻辑) 本

    2024年02月05日
    浏览(59)
  • 【C语言】实现通讯录(动态+文件)

    在之前三子棋和扫雷的基础上,本篇文章博主将给大家逐步分析实现通讯录,介绍通讯录的每个功能( 动态增长和文件保存 )。 —————————————————————— test.c - 测试通讯录 Contact.c - 函数的实现 Contact.h - 函数和类型的声明 以多文件的形式分模块写的

    2024年02月13日
    浏览(57)
  • 【C语言】实现动态版通讯录

    💌内容专栏:【C语言】进阶部分 💌本文概括: 结合自定义类型、动态内存管理知识,对静态版本的通讯录进行优化。 💌本文作者:花 碟 💌发布时间:2023.4.2   目录 前言: 一、静态版本代码实现: 二、动态通讯录  三、代码整理  前面我们学过了结构体、枚举等自定义

    2024年02月02日
    浏览(45)
  • 【C语言】动态通讯录(超详细)

    通讯录是一个可以很好锻炼我们对结构体的使用,加深对结构体的理解,在为以后学习数据结构打下结实的基础 这里我们想设计一个有 添加联系人,删除联系人,查找联系人,修改联系人,展示联系人,排序 这几种功能的通讯录 注意:我们按照三个区域划分 上图所示进行

    2024年02月08日
    浏览(35)
  • C语言实现通讯录--动态版

    实现一个通讯录,联系人的数量可多可少 1.在静态版本的基础上改用动态的方法: (1)默认能够存放三个人的信息 (2)不够的话,每次增加两个人的信息 2.其他功能不变 建立三个文件: test.c 用于测试通讯录的相关功能 contsct.c 通讯录的实现模块(用函数实现功能) conta

    2024年02月15日
    浏览(52)
  • C语言实践——通讯录(2)(动态版)

    首先感谢上一篇博客的大佬们的点赞,非常感谢!!! 目录 前言  一、需要添加的功能 1. 初始化——动态内存开辟 2.添加联系人——通讯录扩容 3.退出通讯录——通讯录销毁 二、具体操作 1.铺垫 2.修改初始化函数 3.修改添加函数  4.退出通讯录,新增销毁函数 上一篇文章我

    2023年04月08日
    浏览(35)
  • C语言动态内存练习:【通讯录(动态内存版本)实现】

    前面我们写了一个静态数组版本的通讯录,再结合刚学习的动态内存管理的知识,我们现在来实现一个动态内存版本的通讯录。 动态内存版本的通讯录,主要还是为了解决静态数组版本的通讯录空间太大导致的内存浪费和空间太小不够存放的问题。 扩容策略: 为通讯录设置

    2023年04月13日
    浏览(72)
  • 【C语言】——通讯录(静态-动态增长-文件储存)

      目录 前言: 一:整体框架 关于通讯录结构体的创建  二:通讯录的功能实现(静态) 2.1初始化通讯录 2.2增加联系人 2.3打印通讯录 2.4删除联系人  2.5 查找联系人 2.6修改联系人  2.7排序联系人 三:通讯录优化——动态内存  3.1通讯录的创建 3.2初始化通讯录  3.3增加联系

    2024年02月07日
    浏览(43)
  • 动态通讯录——C语言【详解+全部码源】

    作者简介: 辭七七,目前大一,正在学习C/C++,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 进阶C语言,本专栏主要讲解数据存储,进阶指针,动态内存管理,文件操作,程序环境和预处理等 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖 我们之前以及写过静态版

    2023年04月21日
    浏览(40)
  • 【C语言】通讯录2.0 (动态增长版)

    通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。 文章的一二三章均于上一篇相同,可以直接看第四章改造内容。 此通讯录是 基于通讯录1.0(静态版)的基础上进行改进 ,请先看系列文章第一篇,再看本篇博客。 ****** 有需要源代码,见

    2024年02月14日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包