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语言实现通讯录(使用文件保存信息)

这两天把动态内存还有文件函数这部分的课听了一下,也跟着把通讯录升级了一下
存储元素不再是固定的了,当存储的元素等于上限时内存就动态增长
每次退出信息又会销毁,可以用fwrite 和 fread让它保存到文件中,不过每次fwrite它就会覆盖之前的内容,所以每次初始化的时候都要先读取出来,等退出了再一次性读取写入文件中,数量多的话速度就会慢,想实现一下,今晚就下了个MySQL,听听网课琢磨琢磨
把这个改进版记录下来

int main()
{
	srand((unsigned int)time(NULL));
	game();
	return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>


#define MAX_NAME 16
#define MAX_SAT 6
#define MAX_TELE 12
#define MAX_ADDR 15
//#define MAX 100
#define DEFAULT_SZ 3

定义在头文件的函数声明
各个的作用都写下来了


void game();
void menu();//菜单
void chushihua(struct uct* p1);
void addformation(struct uct* p1);//增加信息
void showformation(struct uct* p1);//显示信息
void subformation(struct uct* p1);//删除信息
void searchformation(const struct uct* p1);//查找信息
void modifyformation(struct uct* p1);//改动信息
int cmp_stu_name(const void* p1, const void* p2);//比较结构体内的姓名
void IncreasetCapacity(struct uct*p1);//检测存储是否满了
void realise(struct uct* p1);//释放动态内存
void savecontact(struct uct* p1);//保存信息
void loadcontact(struct uct* p1);//从文件中读取信息


enum arr
{
	EXIT,
	ADD,
	SUB,
	SEARCH,
	MODIFY,
	SHOW,
	SORT,
	SAVE
};
struct information
{
	char name[MAX_NAME];
	int age;
	char set[MAX_SAT];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
};
struct uct
{
	struct information *data;
	int size;
	int capacity;
};

我一般喜欢函数从上往下实现

void menu()
{
	printf("*******************************\n");
	printf("*****1 add           2 sub*****\n");
	printf("*****3 search        4 modify**\n");
	printf("*****5 show          6 sort****\n");
	printf("*****7 save          0 exit****\n");
	printf("*******************************\n");
}
void IncreasetCapacity(struct uct* p1);//动态增加信息

void loadcontact(struct uct* p1)
{
	struct information tmp = { 0 };
	FILE* pfRead = fopen("test.dat", "rb");//从文件中读取
	if (pfRead == NULL)//读取失败就返回
	{
		printf("loadcontact::%s", strerror(errno));
		return;
	}
	while (fread(&tmp, sizeof(struct information), 1, pfRead))//读取返回值为零说明没有元素此时循环停止
	{
		IncreasetCapacity(p1);//动态增加信息,判断是否需要增容
		p1->data[p1->size] = tmp;//从文件中读取信息放到临时结构体tmp中,再放到信息结构体中
		p1->size++;//元素作为data下标同时增长
	}
	fclose(pfRead);
	pfRead = NULL;
}
void chushihua(struct uct* p1)//初始化动态信息
{
	//memset(p1->data, 0, sizeof(p1->data));
	p1->data = (struct information*)malloc(DEFAULT_SZ * sizeof(struct information));
	if (p1->data == NULL)
		return;
	p1->size = 0;
	p1->capacity = DEFAULT_SZ;
	loadcontact(p1);
	
}
void savecontact(struct uct* p1)//将结构体中的信息放到创建的文件中
{
	FILE* pfWrite = fopen("test.dat","wb");//创建一个dat文件,wb只写
	if (p1 == NULL)
	{
		printf("%s\n",strerror(errno));
		return;
	}
	int i = 0;
	for (i = 0; i < p1->size; ++i)//有多少元素就写多少个,一次写一个
	{
		fwrite(&(p1->data[i]), sizeof(struct information), 1, pfWrite);
	}
	fclose(pfWrite);//关闭文件
	pfWrite = NULL;
	printf("信息保存成功\n");
}
void IncreasetCapacity(struct uct* p1)//动态增加信息
{
	if (p1->capacity == p1->size)
	{
		p1->capacity += 2;
		struct information* ptr = (struct information*)realloc(p1->data, p1->capacity * sizeof(struct information));
		//如果结构体中的元素超过上限,realloc增加空间
		if (ptr != NULL)
		{
			p1->data = ptr;
			printf("增容成功!\n");
		}
		else
			printf("增容失败!\n");
	}
	
}

void addformation(struct uct* p1)
{
	//检查空间是否满了,如果满了就动态增加
	//如果没满就啥也不干
		IncreasetCapacity(p1);
		printf("请添加信息\n");
		printf("请输入名字 -> \n");
		scanf("%s", p1 ->data[p1->size].name);
		printf("请输入年龄 -> \n");
		scanf("%d",&(p1 ->data[p1->size].age));
		printf("请输入性别 -> \n");
		scanf("%s", p1 ->data[p1->size].set);
		printf("请输入电话 -> \n");
		scanf("%s", p1 ->data[p1->size].tele);
		printf("请输入地址 -> \n");
		scanf("%s", p1 ->data[p1->size].addr);
		printf(" 添加成功 !\n");
		p1->size++;
}
void showformation(struct uct* p1)
{
	int i = 0;
	if (p1->size == 0)
	{
		printf("内容为空\n");
	}
	else//如果不为0就打印信息
	{
		printf("%-16s\t%-3s\t%-6s\t%-12s\t%-15s\n","姓名","年龄","性别","电话","地址");
		for (i = 0; i < p1->size; ++i)
		{
			printf("%-16s\t%-3d\t%-5s\t%-12s\t%-15s\n", p1->data[i].name,
			 p1->data[i].age,
			 p1->data[i].set,
			 p1->data[i].tele,
			 p1->data[i].addr);
		}
	}
}
static int sertch(const struct uct* p1,char name[MAX_NAME])
{
	int i = 0;
	for (i = 0; i < p1->size; ++i)
	{
		if (0 == strcmp(p1->data[i].name, name))
			return i;
	}
	return -1;
}
void subformation(struct uct* p1)
{
	char name[MAX_NAME];
	printf("请输入要删除人的名字");
	scanf("%s", name);
	int ret = sertch(p1,name);
	if (ret == -1)
		printf("该联系人不存在!\n\n");
	else
	{
		while (ret < p1->size - 1)
		{
			p1->data[ret] = p1->data[ret + 1];
			++ret;
		}
		p1->size--;
		printf("删除成功!\n\n");
	}
}
void searchformation(const struct uct* p1)
{
	char name[MAX_NAME];
	printf("请输入你要查找人的姓名:");
	scanf("%s", name);
	int i = sertch(p1, name);
	if (i == -1)
		printf("未查找到该联系人\n");
	else
	{
		printf("%-16s\t %-3s\t %-6s\t %-12s\t %-15s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-16s\t%-3d\t%-5s\t%-12s\t%-15s\n", p1->data[i].name,
			p1->data[i].age,
			p1->data[i].set,
			p1->data[i].tele,
			p1->data[i].addr);
	}
}
void modifyformation(struct uct* p1)
{
	char name[MAX_NAME];
	printf("请输入要修改人的信息:");
	scanf("%s", name);
	int ret = sertch(p1, name);
	if (ret == -1)
	{
		printf("未找到该联系人\n");
	}
	else
	{
		printf("请添加信息\n");
		printf("请输入名字 -> \n");
		scanf("%s", p1->data[ret].name);
		printf("请输入年龄 -> \n");
		scanf("%d", &(p1->data[ret].age));
		printf("请输入性别 -> \n");
		scanf("%s", p1->data[ret].set);
		printf("请输入电话 -> \n");
		scanf("%s", p1->data[ret].tele);
		printf("请输入地址 -> \n");
		scanf("%s", p1->data[ret].addr);
		printf(" xiugai成功 !\n");
	}
}

int cmp_stu_name(const void* p1,const void* p2)//判断结构体中的名字顺序
{
	//return strcmp(((struct information*)p1)->name, ((struct information*)p2)->name);
	return strcmp(((struct information*)p1)->name,((struct information*)p2)->name);
}
void realise(struct uct* p1)//释放空间
{
	free(p1->data);
	p1->data = NULL;
}
void game()
{
	int input = 0;
	struct uct s1;
	chushihua(&s1);
	do
	{
		menu();
		printf("\n");
		printf("\n");
		printf("please input a number:");
		scanf_s("%d", &input);
		int sz = s1.size;
		switch (input)
		{
		case ADD:
			addformation(&s1);//增
			break;
		case SUB:
			subformation(&s1);//删
			break;
		case SEARCH:
			searchformation(&s1);//查
			break;
		case MODIFY:
			modifyformation(&s1);//改
			break;
		case SHOW:
			showformation(&s1);//显示
			break;
		case SORT://排序
			qsort(s1.data, sz, sizeof(s1.data[0]),cmp_stu_name);
			break;
		case SAVE://保存
			savecontact(&s1);
			break;
		case EXIT://退出
			savecontact(&s1);
			realise(&s1);//退出之前释放动态空间
				printf("退出 \n");
				break;
		default :
				printf("输入错误!\n");
				break;
		}

	} while (input);
}

明天把扫雷记录下来吧,有一个地方偏偏不信那个邪就认为自己的那种方法可以实现,改了好多次一直有问题,不过也只是很次的方法,能用自己想的方法实现递归和记录估计会比听懂别人的方法写出来要开心更久?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-19 17:27:06  更:2021-11-19 17:28:37 
 
开发: 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年11日历 -2024/11/24 7:35:43-

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