【C语言】动态通讯录(超详细)

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

通讯录是一个可以很好锻炼我们对结构体的使用,加深对结构体的理解,在为以后学习数据结构打下结实的基础

这里我们想设计一个有添加联系人,删除联系人,查找联系人,修改联系人,展示联系人,排序这几种功能的通讯录


注意:我们按照三个区域划分

【C语言】动态通讯录(超详细),c语言,开发语言

上图所示进行区域划分

  • con.c用来放实现功能的函数
  • con.h用来放头文件的声明
  • test.c用来放整体框架

整体框架:

使用do...while循环创建整体框架

整体框架在test.c中,这部分我们用来测试代码

int main()
{
	int input = 0;
	InitContact(&Con);
	do
	{
		menu();
		printf("请输入你的选项\n");
		scanf("%d", &input);
		switch (input)
		{
		case Add:
			break;
		case Del:
			break;
		case Search:
			break;
		case Modify:
			break;
		case Show:
			break;
		case Sort:
			break;
		case Exit:
			printf("你已成功退出\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}
注意
我在使用case语句时没有用数字1,2,3…
而是使用了枚举常量,因为枚举常量会更方便程序员查看与操作要与菜单的数字相匹配,不然就会弄巧成拙
enum option
{
	Exit,
	Add,
	Del,
	Search,
	Modify,
	Show,
	Sort,
};

菜单:

菜单的设计随心所欲,但要与枚举相匹配

void menu()
{
	printf("**************************\n");
	printf("***   1.Add    2.Del    **\n");
	printf("***   3.Search 4.Modify **\n");
	printf("***   5.Show   6.Sort   **\n");
	printf("***   0.Exit            **\n");
	printf("**************************\n");
	printf("**************************\n");
}

创建通讯录:

此部分我们在Contact.h中创建,在另外两个里include就可以

创建通讯录之前要先创建一个联系人的结构体:
假设我们的结构体包含了一个人的姓名,年龄,性别,电话,住址
那么久可以很好的进行创建:

typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

其中的常量用define按需求进行定义,避免牵一发而动全身的情况

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

因为要动态通讯录
故设计通讯录时不能使用PeoInfo创建数组的方式进行
可以创建结构体指针,指向动态内存分配的空间

typedef struct Contact
{
	PeoInfo* Data;
	int sz;
	int capacity;
}Contact;

最后在test.c文件中创建通讯录 Contact Con;

初始化:

con.c中进行设计,不要忘记在test.c中调用,在con.h中声明
实现功能皆是如此设计,将不在赘述

	void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = START;
	PeoInfo* p = (PeoInfo*)malloc(sizeof(PeoInfo) * START);
	//start为初始化大小,define定义为3
	if (p != NULL)
	{
		pc->Data = p;
	}
	else
	{
		perror("InitContact->malloc");
	}
}

实现功能:

添加联系人:

void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == pc->capacity)
	{
		PeoInfo* str = (PeoInfo*)realloc
		(pc->Data, sizeof(PeoInfo) * 
		(pc->capacity + START_ADD));
		//START_ADD为define定义,为一次扩容数量
		if (str != NULL)
		{
			pc->Data = str;
			pc->capacity = pc->capacity + START_ADD;
			printf("增容成功\n");
		}
		else
		{
			perror("AddContact->realloc");
			return;
		}
	}
	printf("输入名字\n");
	scanf("%s", pc->Data[pc->sz].name);
	printf("输入年龄\n");
	scanf("%d", &pc->Data[pc->sz].age);
	printf("输入性别\n");
	scanf("%s", &pc->Data[pc->sz].sex);
	printf("输入电话\n");
	scanf("%s", &pc->Data[pc->sz].tele);
	printf("输入住址\n");
	scanf("%s", &pc->Data[pc->sz].addr);
	printf("输入成功\n");
	pc->sz++;
}

删除联系人:

void DelContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需删除\n");
		return;
	}
	char name[NAME_MAX];
	printf("输入你要删除人的姓名\n");
	scanf("%s", name);
	int ret = find(pc, name);
	//我们这里使用了find函数
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	for (int i = ret; i < pc->sz-1; i++)
	{
		pc->Data[i] = pc->Data[i + 1];
	}
	pc->sz--;
}

我们在输入查找姓名后要进行查找,因此我们设计了一个find函数,方便别的函数的使用

find()的定义:

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

查找联系人:

void SearchContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	char name[NAME_MAX];
	printf("输入你要查找人的姓名\n");
	scanf("%s", name);
	int ret = find(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年龄", "性别", "电话", "住址");
	printf(" % -20s % -5d % -5s % -20s % -20s\n",
		pc->Data[ret].name, pc->Data[ret].age, pc->Data[ret].sex, pc->Data[ret].tele, pc->Data[ret].addr);
}

修改联系人:

void ModifyContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	char name[NAME_MAX];
	printf("输入你要修改人的姓名\n");
	scanf("%s", name);
	int ret = find(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	printf("输入名字\n");
	scanf("%s", pc->Data[ret].name);
	printf("输入年龄\n");
	scanf("%d", &pc->Data[ret].age);
	printf("输入性别\n");
	scanf("%s", &pc->Data[ret].sex);
	printf("输入电话\n");
	scanf("%s", &pc->Data[ret].tele);
	printf("输入住址\n");
	scanf("%s", &pc->Data[ret].addr);
	printf("输入成功\n");
}

展示联系人:

void ShowContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需打印\n");
		return;
	}
	printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年龄", "性别", "电话", "住址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf(" % -20s % -5d % -5s % -20s % -20s\n",
			pc->Data[i].name, pc->Data[i].age, pc->Data[i].sex, pc->Data[i].tele, pc->Data[i].addr);
	}
}

排序:

排序可以按照名字排,或是年龄,亦或是性别等等
这里我们只进行名字的排序,使用方法大同小异(快排)

int cmp_name(void* e1,void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
	qsort(pc->Data, pc->sz, sizeof(PeoInfo), cmp_name);
}

free空间:

最后一步就是释放空间有始有终

void DestoryContact(Contact* pc)
{
	free(pc->Data);
	pc->Data=NULL;
	pc->sz=0;
	pc->capacity=0;
}

源代码:

con.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

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


//void InitContact(Contact* pc)
//{
//	assert(pc);
//	pc->sz = 0;
//	memset(pc->Data, 0, sizeof(pc->Data));
//}
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = START;
	PeoInfo* p = (PeoInfo*)malloc(sizeof(PeoInfo) * START);
	if (p != NULL)
	{
		pc->Data = p;
	}
	else
	{
		perror("InitContact->malloc");
	}
}

void DestoryContact(Contact* pc)
{
	free(pc);
}


void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == pc->capacity)
	{
		PeoInfo* str = (PeoInfo*)realloc(pc->Data, sizeof(PeoInfo) * (pc->capacity + START_ADD));
		if (str != NULL)
		{
			pc->Data = str;
			pc->capacity = pc->capacity + 2;
			printf("增容成功\n");
		}
		else
		{
			perror("AddContact->realloc");
			return;
		}
	}
	printf("输入名字\n");
	scanf("%s", pc->Data[pc->sz].name);
	printf("输入年龄\n");
	scanf("%d", &pc->Data[pc->sz].age);
	printf("输入性别\n");
	scanf("%s", &pc->Data[pc->sz].sex);
	printf("输入电话\n");
	scanf("%s", &pc->Data[pc->sz].tele);
	printf("输入住址\n");
	scanf("%s", &pc->Data[pc->sz].addr);
	printf("输入成功\n");
	pc->sz++;
}

void ShowContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需打印\n");
		return;
	}
	printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年龄", "性别", "电话", "住址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf(" % -20s % -5d % -5s % -20s % -20s\n",
			pc->Data[i].name, pc->Data[i].age, pc->Data[i].sex, pc->Data[i].tele, pc->Data[i].addr);
	}
}

void DelContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需删除\n");
		return;
	}
	char name[NAME_MAX];
	printf("输入你要删除人的姓名\n");
	scanf("%s", name);
	int ret = find(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	for (int i = ret; i < pc->sz-1; i++)
	{
		pc->Data[i] = pc->Data[i + 1];
	}
	pc->sz--;
}

void SearchContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	char name[NAME_MAX];
	printf("输入你要查找人的姓名\n");
	scanf("%s", name);
	int ret = find(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年龄", "性别", "电话", "住址");
	printf(" % -20s % -5d % -5s % -20s % -20s\n",
		pc->Data[ret].name, pc->Data[ret].age, pc->Data[ret].sex, pc->Data[ret].tele, pc->Data[ret].addr);
}

void ModifyContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	char name[NAME_MAX];
	printf("输入你要修改人的姓名\n");
	scanf("%s", name);
	int ret = find(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	printf("输入名字\n");
	scanf("%s", pc->Data[ret].name);
	printf("输入年龄\n");
	scanf("%d", &pc->Data[ret].age);
	printf("输入性别\n");
	scanf("%s", &pc->Data[ret].sex);
	printf("输入电话\n");
	scanf("%s", &pc->Data[ret].tele);
	printf("输入住址\n");
	scanf("%s", &pc->Data[ret].addr);
	printf("输入成功\n");
}

int cmp_name(void* e1,void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
	qsort(pc->Data, pc->sz, sizeof(PeoInfo), cmp_name);
}

con.h

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

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

#define START 3
#define START_ADD 2

typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;


typedef struct Contact
{
	PeoInfo* Data;
	int sz;
	int capacity;
}Contact;

//init
void InitContact(Contact* pc);

//add
void AddContact(Contact* pc);

//show
void ShowContact(Contact* pc);

//del
void DelContact(Contact* pc);

//search
void SearchContact(Contact* pc);

//modify
void ModifyContact(Contact* pc);

//sort
void SortContact(Contact* pc);

//destory
void DestoryContact(Contact* pc);

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

enum option
{
	Exit,
	Add,
	Del,
	Search,
	Modify,
	Show,
	Sort,
};


void menu()
{
	printf("**************************\n");
	printf("***   1.Add    2.Del    **\n");
	printf("***   3.Search 4.Modify **\n");
	printf("***   5.Show   6.Sort   **\n");
	printf("***   0.Exit            **\n");
	printf("**************************\n");
	printf("**************************\n");
}
int main()
{
	int input = 0;
	Contact Con;
	InitContact(&Con);
	do
	{
		menu();
		printf("请输入你的选项\n");
		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 Sort:
			SortContact(&Con);
			break;
		case Exit:
			DestoryContact(&Con);
			printf("你已成功退出\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;

		}
	} while (input);
	return 0;
}

欢迎纠错与讨论文章来源地址https://www.toymoban.com/news/detail-721049.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日
    浏览(46)
  • C语言实现通讯录--动态版

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

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

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

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

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

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

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

    2024年02月14日
    浏览(42)
  • 【C语言】——通讯录(静态-动态增长-文件储存)

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

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

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

    2023年04月21日
    浏览(41)
  • 【C语言实战项目】通讯录(动态增容版)

    🦄 个人主页 :修修修也 🎏 所属专栏 :数据结构 ⚙️ 操作环境 : Visual Studio 2022 目录 一.动态增容版简介 二.动态增容版逐步实现详解 1.创建通讯录 2. 初始化通讯录 3.增加联系人 4.通讯录增容 5.销毁通讯录 三.动态增容版代码整合 contact.c test.c contact.h 上篇博客我们一起用C语言

    2024年02月11日
    浏览(41)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包