返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言实现一个文件版动态通讯录流程详解
  • 887
分享到

C语言实现一个文件版动态通讯录流程详解

C语言动态通讯录C语言通讯录 2023-01-29 18:01:15 887人浏览 泡泡鱼
摘要

目录通讯录思维导图一、Contact.h二、Contact.c1.初始化通讯录2.检查容量是否满3.添加联系人4.显示联系人5.查找联系人6.修改联系人7.通过名字来排序联系人8.保

通讯录思维导图

一、Contact.h

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 11
#define ADDR_MAX 30
#define INIT_CAPA 3
#define INC_CAPA 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;
//初始化通讯录
void InitContact(Contact* pc);
//添加联系人
void AddContact(Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//显示通讯录
void ShowContact(const Contact* pc);
//查找联系人
void SearchContact(Contact*pc);
//修改联系人'
void ModifyContact(Contact*pc);
//通过名字排序联系人
void ByNameSortContact(Contact* pc);
//销毁联系人
void DestroyContact(Contact* pc);
//保存联系人到文本文件中
void SaveContact(Contact* pc);
//从文件中读取联系人的信息
void GetContact(Contact* pc);

这些是头文件的包含,函数的声明,以及#define定义的常量,为了以后修改方便

二、Contact.c

1.初始化通讯录

void InitContact(Contact* pc)//初始化通讯录
{
	assert(pc!=NULL);
	pc-> sz = 0;
	pc->capacity = INIT_CAPA;
	PeoInfo * ptr = (PeoInfo*)calloc(INIT_CAPA, sizeof(PeoInfo));
	if (ptr == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->data = ptr;
	GetContact(pc);
}

初始化通讯录的容量开始为3,sz初始时为0,动态开辟的ptr开辟成功在赋给data。

2.检查容量是否满

void check_capacity(Contact* pc)//检查容量是否满
{
	assert(pc);
	if (pc->capacity == pc->sz)
	{
		PeoInfo*ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity");
			return;
		}
		pc->data = ptr;
		pc->capacity += INC_CAPA;
		printf("增容成功\n");
	}
}

如果容量满,则每次增容两个,如果想要增容更多,则修改define定义的常量就可以修改了。

realloc开辟的时候有可能是用pc->data来往后扩大增容,也有可能是用新的空间来开辟,为了防止开辟失败,使原有的数据丢失,则先使用新的指针变量来接收动态开辟的空间,如果开辟成功,再将它赋给data。

3.添加联系人

void AddContact(Contact* pc)//添加联系人
{
	assert(pc != NULL);
	check_capacity(pc);
	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++;
}

添加联系人前,需要先判断是否需要增容

4.显示联系人

void ShowContact(const Contact* pc)//显示联系人
{
	assert(pc != NULL);
	printf("%-20s\t%-4s\t%-4s\t%-12s\t%-30s\n","姓名","年龄","性别","电话号码","地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-4s\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);
	}
}

5.查找联系人

int ByNameFind(Contact* pc, char name[])//通过名字查找联系人
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void SearchContact(Contact* pc)//查找联系人
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要查找的联系人\n");
	scanf("%s", name);
	int ret = ByNameFind(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	printf("%-20s\t%-4s\t%-4s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话号码", "地址");
	printf("%-20s\t%-4d\t%-4s\t%-12s\t%-30s\n", pc->data[ret].name,
		pc->data[ret].age,
		pc->data[ret].sex,
		pc->data[ret].tele,
		pc->data[ret].addr);
}

注意:名字属于字符串,名字的比较需要用strcmp来比较,如果返回-1,则是没有找到联系人,如果找到了,则就打印这个联系人的信息出来

6.修改联系人

void ModifyContact(Contact* pc)//修改联系人
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要修改的联系人姓名\n");
	scanf("%s", name);
	int pos = ByNameFind(pc, name);
	if (pos == -1)
	{
		printf("找不到该联系人\n");
		return;
	}
	printf("请输入姓名:\n");
	scanf("%s", pc->data[pos].name);
	printf("请输入年龄:\n");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入性别:\n");
	scanf("%s", pc->data[pos].sex);
	printf("请输入号码:\n");
	scanf("%s", pc->data[pos].tele);
	printf("请输入地址:\n");
	scanf("%s", pc->data[pos].addr);
	printf("修改联系人成功\n");
}

注意:想要修改这个联系人,也需要通讯录中有这个联系人,所以要先查找到这个联系人,所以调用封装好的通过名字查找联系人这个函数就可以了,如果返回-1,则就是没有该联系人,无法修改,如果找到了,则才能够修改此联系人的信息。

7.通过名字来排序联系人

void ByNameSortContact(Contact* pc)//通过名字来排序
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("无联系人,无法排序\n");
		return;
	}
	PeoInfo temp;
	for (int i = 0; i < pc->sz - 1; i++)
	{
		for(int j = 0 ;j<pc->sz-1-i;j++)
		{
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
			{
				temp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = temp;
			}
		}
	}
	printf("排序成功\n");
}

注意:这里通过名字来排序联系人,也是需要用到strcmp这个库函数的,strcmp是一个字符来比较的,如果有一个字符大的话就要进行交换,利用的是冒泡排序思想来排序联系人的

8.保存联系人到文本文件中

void SaveContact(Contact* pc)
{
	assert(pc);
	
	FILE* pf = fopen("Contact.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
	}
	else
	{
		for (int i = 0; i < pc->sz; i++)
		{
			fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
		}
		fclose(pf);
		pf = NULL;
		printf("保存数据成功\n");
	}
}

注意:FILE是C语言标准的指针,wb是用二进制的方式写入文本文件中,而fwrite的用法我们可以利用cplusplus来查找它的用法,里面介绍了它的每个参数的用法,第一个参数ptr其实就是传我们的data的指针进去,第二个参数本质就是求大小的,求得是PeoInfo得大小,第三个参数就是每次添加几个联系人,每次添加1个。第四个参数是把文件流放入

9.从文件中读取联系人的信息

//从文件中初始化联系人
void GetContact(Contact* pc)
{
	assert(pc);
 
	FILE* pf = fopen("Contact.txt", "rb");
	if (pf == NULL)
	{
		perror("GetContact::fopen");
	}
	else
	{
		PeoInfo ptr = { 0 };
		int i = 0;
		while (fread(&ptr, sizeof(PeoInfo), 1, pf))
		{
			check_capacity(pc);
			pc->data[i] = ptr;
			i++;
			pc->sz++;
		}
		fclose(pf);
		pf = NULL;
	}
}

注意:rb是利用二进制来读取联系人的,fread的用法如上图所示。

10.销毁联系人

//销毁联系人
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}

注意:在我们退出通讯录时,要将它进行销毁

三、text.c

#include"Contact.h"
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");
}
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
int main()
{
	Contact con;
	InitContact(&con);
	int input = 0;
	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:
			ByNameSortContact(&con);
			break;
		case EXIT:
			SaveContact(&con);
			DestroyContact(&con);
			printf("退出程序\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;

注意:首先要建立菜单,然后用枚举来定义case后面,这样为了可以让我们看代码更清晰,在运行程序时要将联系人从文件中读取出来,在退出文件时,要把联系人保存到文本文件中去,在进行销毁。

好了,小编的分享到这里就结束了,如果有什么不足的地方请大佬多多指教!!!

到此这篇关于C语言实现一个文件版动态通讯录流程详解的文章就介绍到这了,更多相关C语言动态通讯录内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言实现一个文件版动态通讯录流程详解

本文链接: https://lsjlt.com/news/178688.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C语言实现一个文件版动态通讯录流程详解
    目录通讯录思维导图一、Contact.h二、Contact.c1.初始化通讯录2.检查容量是否满3.添加联系人4.显示联系人5.查找联系人6.修改联系人7.通过名字来排序联系人8.保...
    99+
    2023-01-29
    C语言动态通讯录 C语言通讯录
  • C语言静态与动态通讯录的实现流程详解
    目录静态通讯录contact.hcontact.ctest.c动态通讯录contact.hcontact.cqsort.ctest.c本次通讯录的代码已经放到我的Gitee仓库中,感...
    99+
    2024-04-02
  • C语言与C++动态通讯录超详细实现流程
    目录1、思路以及要实现的功能2、详细步骤2.1 打印菜单界面(建一个源文件test.c)2.2 主函数2.3 初始化函数与加载函数2.4 增加联系人函数AddContact2.5 删...
    99+
    2024-04-02
  • C语言示例讲解动态/文件/静态功能版本的通讯录实现
    目录一、代码展示test.ccontact.ccontact.h二、效果展示静态版本基本功能的实现动态版本扩容功能的实现文件版本保存本地功能实现一、代码展示 test.c ✅使用枚举...
    99+
    2024-04-02
  • C语言模拟实现动态通讯录
    目录1.模拟实现通讯录总体架构一览图2.文件执行任务3.分模块实现 测试模块 test.c头文件 功能函数声明 contact.h功能函数逐一实现1.模拟实现通讯录总体架构...
    99+
    2024-04-02
  • C语言实现可增容动态通讯录详细过程
    目录创建可自动扩容的通讯录添加用户信息删除用户信息查找联系人修改用户信息以名字将用户排序销毁通讯录创建可自动扩容的通讯录 这里我们想实现通讯录自动扩容,不够了能扩大内存,变得稍微有点...
    99+
    2024-04-02
  • C语言实现动态版通讯录的代码分享
    目录前言初始化函数具体实现代码检查容量函数实现代码销毁通讯录函数实现代码动态版通讯录完整代码前言 哈喽各位友友们,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下!我仅已...
    99+
    2023-01-12
    C语言动态版通讯录 C语言动态通讯录 C语言 通讯录
  • C语言动态与静态分别实现通讯录详细过程
    目录前言:一.静态通讯录的实现1.环境的分工逻辑2.待实现的功能3.contact.h4.contact.c5.test.c6.实现效果二.通讯录动态的实现1.contact.h2....
    99+
    2024-04-02
  • 详解C语言之实现通讯录
    目录基本思路和代码实现其他探讨总结基本思路和代码实现 为了代码清晰易读,我们创建一个Main.c源文件用来实现代码的基本逻辑。创建一个Contact.h源文件用于封装实现功能的函数,...
    99+
    2024-04-02
  • C语言静态动态两版本通讯录实战源码
    目录正片开始静态版本头文件( phonebook.h)接口(test.c)功能板块(phonebook.c)1. 初始化:2. 增添:3.查找4.删除5.修改6.排序7.全览静态版全...
    99+
    2024-04-02
  • C语言实现文件版通讯录的代码分享
    目录一、前言二、静态版+动态版通讯录的实现三、区别于静态版+动态版通讯录的函数实现文件版通讯录完整代码一、前言 哈喽各位友友们,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分...
    99+
    2023-01-12
    C语言文件版通讯录 C语言文件通讯录 C语言通讯录
  • C语言怎么模拟实现动态通讯录
    本篇内容主要讲解“C语言怎么模拟实现动态通讯录”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言怎么模拟实现动态通讯录”吧!目录模拟实现通讯录总体架构一览图文件执行任务分模块实现 测...
    99+
    2023-06-20
  • C语言实现通讯录的方法(包括静态版本和动态版本)
    目录1.静态通讯录的实现实现的方法:2.动态通讯录的实现实现的方法:3.总结1.静态通讯录的实现 实现的方法: 我们采用的方法就是工程形势,实现将功能和定义以及测试分成三个文件,其中...
    99+
    2024-04-02
  • C语言静态版通讯录的设计与实现
    目录1. 配置运行环境2. 通讯录的实现2.1 通讯录的功能目录2.2 增加信息功能代码的实现2.3 显示信息功能代码的实现2.4 删除信息功能代码的实现2.5 查询信息功能代码的实...
    99+
    2023-05-16
    C语言静态版通讯录 C语言通讯录实现
  • C语言实现简易通讯录完整流程
    目标:通讯录可以存放1000个人信息,人的信息:性别名字年龄电话住址 菜单打印 1.增加联系人 2.删除联系人 3.查找联系人(修改) 4.名字排序联系人 5.展示 6.清空 分析:...
    99+
    2024-04-02
  • C语言多功能动态通讯录实现示例
    目录前言一、预设置1,头文件的包含2,联系人的信息格式3,通讯录的信息格式4,通讯录相关宏定义5,通讯录功能枚举6,基本主函数二、功能函数实现1,初始化函数2,查找函数3,打印菜单4...
    99+
    2023-01-31
    C语言多功能动态通讯录 C语言 通讯录
  • C语言实现静态版通讯录的代码分享
    目录前言通讯录设计的关键思想点分析 通讯录界面(meun)设计 增加信息功能实现代码删除信息功能实现代码查询信息功能实现代码修改信息功能实现代码按年龄升序排序信息...
    99+
    2023-01-12
    C语言静态通讯录 C语言通讯录
  • C语言实现通讯录程序
    本文实例为大家分享了C语言实现通讯录程序的具体代码,供大家参考,具体内容如下 设计要求: 可以存放1000个人的信息,每个人的信息包括姓名、年龄、性别、电话、住址 通讯录功能包括: ...
    99+
    2024-04-02
  • 用c语言编写一个通讯录代码详解
    目录实现通讯录的思路如下:总结实现通讯录的思路如下: 1.程序运行起来时用户首先要看到菜单栏选项并且对应菜单栏所给出的选项做出选择,这里我们简单设计一个Menu()函数可以让用户看见...
    99+
    2024-04-02
  • C语言编程动态内存开辟实现升级版通讯录教程示例
    目录前言一、存放联系人信息二、通讯录初始化三、增加联系人四、销毁通讯录后记前言 所谓动态内存开辟的通讯录,就是我需要多少联系人,就给多少联系人,防止给定一个联系人上限,需要增加联系人...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作