IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 《C语言通讯录》完全体:动态开辟、文件载入、名字排序 -> 正文阅读

[C++知识库]《C语言通讯录》完全体:动态开辟、文件载入、名字排序

伪代码

  • 通讯录人的各项信息,用结构体类型变量表示,多个人的信息用结构体指针数组存放。
  • 需要一个量表示:当前数组已经存了几个人的信息。
  • 需要一个量表示:这个数组的大小,存满了就动态开辟扩容。
  • 三个量封装便是一个通讯录结构体类型,创建一个变量,咱们就可以制作通讯录了。
  • 初始化开辟多少空间,每次增加多少空间,#define解决。
  • 文件载入注意检查容量,每次读一个,直至读完。

主函数.c

枚举:建议全部大写

enum Option
{
	EXIT,
	add,
	del,
	search,
	modify,
	sort,
	save,
	show
};

菜单:和枚举一一对应

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

主函数

int main()
{
	int options = 0;
	Contact con;  创建通讯录 ,需要初始化,加载文件,动态开辟内存。
	InintContact(&con);
	do
	{
		menu();
		printf("请选择操作:>");
		scanf("%d", &options);
		switch (options)
		{
		case add:
			ADDcontact(&con);
			break;
		case del:
			DelCon(&con);
			break;
		case search:
			SearchCon(&con);
			break;
		case modify:
			ModifyCon(&con);
			break;
		case save:
			SaveCon(&con);
			break;
	     case sort:
			SortCon(&con);
			break;
		case show:
			ShowCon(&con);
			break;
		case EXIT:
			ExittCon(&con);
			break;
		default:
			printf("选择错误,请重新输入\n");
			break;
		}
	} while (options);
}

通讯录.h

各项函数的声明,宏的定义:为了以后操作更改数据方便.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define NAME 20
#define SEX 5
#define TEL 13
#define ADRESS 30

#define CAPACITY 3 初始三个
#define INS_SZ 2 每次增加几个空间

typedef struct People
{
	char name[NAME];
	char sex[SEX];
	int age;
	char tel[TEL];
	char address[ADRESS];
}PI;

typedef struct Contact
{
	PI* data;
	int sz;
	int cap;
}Contact;


void InintContact(Contact* pc);

void ShowCon(Contact* pc);

void DelCon(Contact* pc);

void ExittCon(Contact* pc);

void SaveCon(Contact* pc);

void SearchCon(Contact* pc);

void ADDcontact(Contact* pc);
 
void ModifyCon(Contact* pc);

void SortCon(Contact* pc);

通讯录.c

初始化通讯录

void InintContact(Contact* pc)
{
	pc->data = (PI*)calloc(CAPACITY, sizeof(PI));
	if ( pc->data == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->sz = 0;
	pc->cap = CAPACITY;
	LoadContact(pc);
}

加载通讯录

void LoadContact(Contact* pc)
{
	使用文件前,先打开,会有文件指针返回,打开后记得关闭
	FILE* pf = fopen("txl.data", "r");
	if (pf == NULL)
	{
		perror("load");
		return;
	}
	PI tmp = { 0 }; 从文件读取内容,需要一个地方暂存
	while (fread(&tmp,sizeof(PI),1,pf)  fread 每次读取返回 读取到的完整元素的个数,直至读完整个文件返回0
	{
		Checkcap(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	printf("加载成功....!\n");
	fclose(pf);
	pf = NULL;
}

增容

void Checkcap(Contact* pc)
{
	if (pc->sz == pc->cap)
	{
		PI* ptr = (PI*)realloc(pc->data, (CAPACITY + INS_SZ) * sizeof(PI));
		if (ptr != NULL)
		{
			扩容成共,新地址交给指向结构体区域的data,容量+=SZ
			pc->data = ptr;
			pc->cap += INS_SZ;
			printf("扩容成功\n");
		}
		else
		{
			perror("Check");
			printf("增容失败\n");
		}
	}
}

打印显示

  • %20s-打印20个字符,不够空格填充
  • - 左对齐 \t 工整一点
void ShowCon(Contact* pc)
{
	printf("%-20s\t%-5s\t%-5s\t%-13s\t%-30s\n","姓名", "性别", "年龄", "手机号", "住址");
	int i = 0;
	for ( i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-13s\t%-30s\n", 
			pc->data[i].name,
			pc->data[i].sex, 
			pc->data[i].age, 
			pc->data[i].tel, 
			pc->data[i].address);
	}
}

增加

void ADDcontact(Contact* pc)
{
	Checkcap(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].tel);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->sz].address);

	pc->sz++;
	printf("增加成功\n");
}

删除

删除,修改,查找都需要 搜索比较 的功能,所以功能独立出来写一个函数。

void DelCon(Contact* pc)
{
	int pos = 0;
	char name[NAME] = { 0 };
	if (pc->sz==0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	else
	{
		printf("请输入删除人的名字:");
		scanf("%s\n", name);
		字符串比较,返回下标,删除往前覆盖
		pos = FindByname(pc,name);
		if (pos ==0)
		{
			printf("要删除人的名字不存在\n");
			return;
		}
		else
		{
			int i = 0;
			for ( i = pos; i < pc->sz-1; i++)// 0 1 2 3  a b c d			
			{
				pc->data[i] = pc->data[i + 1];
			}
			pc->sz--;
			printf("The deletion was successful\n");
		}
	}
}

查找比较函数,static修饰…只能在本源文件内部用,外面看不到

static int  FindByname(const Contact* pc,char name[])
{
	int i = 0;
	for ( i = 0; i < pc->sz; i++)
	{
		while (strcmp(pc->data[i].name,name)== 0)
		{
			return i;
		}
	}
	return 0;
}

修改和查找

void ModifyCon(Contact* pc)
{
	int pos = 0;
	char name[NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,修改信息不存在\n");
		return;
	}
	else
	{
		printf("请输入要修改人的名字:");
		scanf("%s\n", name);
		pos = FindByname(pc, name);
		if (pos == 0)
		{
			printf("查无此人,无法完成修改\n");
			return;
		}
		else
		{
			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].tel);
			printf("请输入地址:>");
			scanf("%s", pc->data[pos].address);

			printf("修改成功!");
		}
	}
}
void SearchCon(Contact* pc)
{
	int pos = 0;
	char name[NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,查找的人的名字不存在\n");
		return;
	}
	else
	{
		printf("请输入要查找人的名字:");
		scanf("%s\n", name);
		pos = FindByname(pc, name);
		if (pos == 0)
		{
			printf("不好意思,查无此人\n");
			return;
		}
		else
		{
			printf("%-20s\t%-5s\t%-5d\t%-13s\t%-30s\n", 
				pc->data[pos].name,
				pc->data[pos].sex, 
				pc->data[pos].age, 
				pc->data[pos].tel, 
				pc->data[pos].address);
		}
	}
}

按名字排序

利用的是库函数…qsort

int compare(const void* a, const void* b)
{
	PI* pa = (PI*)a;
	PI* pb = (PI*)b;
	return strcmp(pa->name, pb->name);
}

void SortCon(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(PI), compare);
	ShowCon(pc);
}

保存通讯录和退出

保存

void SaveCon(Contact* pc)
{
	FILE* pf = fopen("txl.data", "w");
	if (pf==NULL)
	{
		perror("SaveCon");
		return;
	}
	else
	{
		int i = 0;
		for ( i = 0; i < pc->sz; i++)
		{
			fwrite(pc->data+i, sizeof(PI), 1, pf);
		}
		printf("保存成功!");
	}
	fclose(pf);
	pf = NULL;
}

退出

void ExittCon(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->cap = 0;
}

成果展示

二进制写入
二进制读取

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 17:55:54  更:2022-05-24 17:58:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 21:10:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码