动态内存通讯录(顺序表+文件)

目录

一:效果展示

二:代码部分

1,主函数逻辑(main)

2,顺序表(SeqList)

3,通讯录(Contact)

4,文件保存与读取(FILE)

三:总体代码整理


一:效果展示

共5个功能:1.添加联系人

                    2.删除联系人

                    3.修改联系人  

                    4.查找联系人

                    5.展示联系人

没有提前创建文件不用担心,当你第一次运行之后选择保存文件是会在文件以二进制打开时自动创建这个文件!!!

第一次进入会有文件打开失败的提示,不用担心,这是因为还没有创建这个文件

 添加联系人

 展示联系人

 查找联系人

 删除联系人

 修改联系人

 退出并保存

二:代码部分

在代码中出现部分getchar()函数消除缓冲区的回车字符,以此更好的读取数据避免数据冲突。

getchar()函数也可以阻止程序的运行,如程序最后用getchar()阻止程序退出并起到由人的操作来控制退出的效果(回车退出程序)。

1,主函数逻辑(main)

主函数main.c的操作逻辑(逻辑原理写在注释中)。

#ifndef _SEQLIST_H
#define _SEQLIST_H

#include "SeqList.h"

#endif

//菜单
void menu(Contact* con)
{
	printf("***************************************************\n");
	printf("********************  通讯录  *********************\n");
	printf("************1.添加联系人   2.删除联系人************\n");
	printf("************3.修改联系人   4.查找联系人************\n");
	printf("************5.展示联系人   0.退出通讯录************\n");
	printf("************    联系人数量:%d/%d  ****************\n",con->size,con->capacity);
	printf("***************************************************\n");
}


//主函数逻辑
int main()
{
	int op = -1;//操作选项变量
	Contact con;//创建通讯录变量
	ContactInit(&con);//初始化通讯录
	LoadContact(&con);//下载文件内容至通讯录

	do {
		menu(&con);//打印菜单
		printf("请选择您的操作:");
		scanf_s("%d", &op);//保存操作
		getchar();//消除缓冲区的回车字符

		//对应op执行操作
		switch (op)
		{
		case 1:
			ContactAdd(&con);//添加联系人
			break;
		case 2:
			ContactDel(&con);//删除联系人
			break;
		case 3:
			ContactModify(&con);//修改联系人数据
			break;
		case 4:
			ContactFind(&con);//查找联系人
			break;
		case 5:
			ContactShow(&con);//展示所有联系人
			break;
		case 0:
			printf("推出通讯录......\n");//退出
			break;
		default:
			printf("不存在此操作!\n");//操作不存在
			break;
		}
	} while (op);//op==0即选择退出操作时退出循环

	char ch;//创建文件是否保存的变量
	//是否保存此次对通讯录的修改
	do {
		printf("是否保存此次更改(Y/N)(y/n):");
		ch = getchar();//读取选项
		switch (ch)
		{
		case 'y':case 'Y':
			SaveContact(&con);//把通讯录内容保存到文件中
			printf("保存成功!\n");
			break;
		case 'n':case 'N':
			printf("未保存!\n");
			break;
		default:
			printf("没有此选项!请重新选择:\n");
		}

	} while (ch != 'n' && ch != 'N' && ch != 'y' && ch != 'Y');
	
	ContactDestory(&con);//销毁通讯录

	printf("按回车键退出程序!");

	getchar();//消除在输入ch后的回车字符
	getchar();//再次输入回车后退出程序

	return 0;
}

2,顺序表(SeqList)

采用动态顺序表,优点在于可以根据实际联系人个数的多少 开辟合适的空间,避免了空间的大量浪费。

动态顺序表头文件(SeqList.h)

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "Contact.h"


//#define N 100
//
//静态顺序表
//struct SeqList_Static
//{
//	int arr[N];
//	int size;
//};

typedef peoInfo SLDateType;//对联系人结构体的声明--用于两个头文件要相互引用的情况

//动态顺序表
typedef struct SeqList
{
	SLDateType* arr;//数组--底层逻辑是数组的连续性--保存联系人数据
	int size;//有效数据个数
	int capacity;//开辟的空间大小
}SL;

//顺序表初始化
void SLInit(SL* ps);

//顺序表销毁
void SLDestory(SL* ps);

//头部插入删除/尾部插入删除
void SLPushBack(SL* ps, SLDateType x);//尾插
void SLPushFront(SL* ps, SLDateType x);//头插
void SLPopBack(SL* ps);//尾删
void SLPopFront(SL* ps);//头删

//指定位置的插入删除
void SLInsert(SL* ps, int pos, SLDateType x);//插入
void SLErase(SL* ps, int pos);//删除

//顺序表的查找
int SLFind(SL* ps, SLDateType x);

//打印顺序表
void SLPrrintf(SL s);

 动态顺序表c文件(SeqList.c)

#ifndef _SEQLIST_H
#define _SEQLIST_H

#include "SeqList.h"

#endif

//顺序表初始化
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

//顺序表销毁
void SLDestory(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

//判断空间够不够--扩容
void SLcheckCapacity(SL* ps)
{
	//插入前判断空间够不够
	if (ps->capacity == ps->size)
	{
		//申请空间--增容--realloc
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//三目操作符
		SLDateType* tmp = (SLDateType*)realloc(ps->arr, newCapacity * sizeof(SLDateType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}

//尾插
void SLPushBack(SL* ps, SLDateType x)
{
	//断言
	assert(ps);
	//插入前判断空间够不够
	SLcheckCapacity(ps);
	//尾部插入x
	ps->arr[ps->size++] = x;
}

//头插
void SLPushFront(SL* ps, SLDateType x)
{
	//断言
	assert(ps);
	//插入前判断空间够不够
	SLcheckCapacity(ps);
	//移动数据位置--后移一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	//头部插入x
	ps->arr[0] = x;
	ps->size++;
}

//尾删
void SLPopBack(SL* ps)
{
	//断言
	assert(ps);//ps是否为NULL
	assert(ps->size);//size是否为0
	//尾部删除
	--ps->size;
}

//头删
void SLPopFront(SL* ps)
{
	//断言
	assert(ps);//ps是否为NULL
	assert(ps->size);//size是否为0
	//头部删除--所有数据向前移动一位
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	--ps->size;
}

//在指定位置之前插入
void SLInsert(SL* ps, int pos, SLDateType x)
{
	//断言
	assert(ps);//ps是否为NULL
	assert(pos >= 0 && pos <= ps->size);
	//插入前判断空间够不够
	SLcheckCapacity(ps);
	//插入
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}

//指定位置删除
void SLErase(SL* ps, int pos)
{
	//断言
	assert(ps);//ps是否为NULL
	assert(pos >= 0 && pos < ps->size);
	//shanchu
	for (int i = pos; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

//顺序表的查找--由于通讯录数据类型的不同--数据查找将在Contact.c中重写
//int SLFind(SL* ps, SLDateType x)
//{
//	//断言
//	assert(ps);//ps是否为NULL
//	for (int i = 0; i < ps->size; i++)
//	{
//		if (ps->arr[i] == x)
//		{
//			return i;
//		}
//	}
//	return -1;
//}

//打印顺序表--由于通讯录数据类型的不同--数据打印将在Contact.c中重写
//void SLPrrintf(SL s)
//{
//	if (s.size)
//	{
//		for (int i = 0; i < s.size; i++)
//		{
//			printf("%d ", s.arr[i]);
//		}
//	}
//	else
//	{
//		printf("无有效数据:size=0");
//	}
//	printf("\n");
//}

3,通讯录(Contact)

基于动态顺序表的函数实现通讯录函数的编写

代码中的  gets_s可用gets或scanf(“%s“,...)替换;scanf_s可用scanf替换

通讯录头文件(Contact.h)

#pragma once

#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100

//联系人数据结构
typedef struct personInfo
{
	char name[NAME_MAX];//姓名
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//地址
	char birthday[20];//生日
}peoInfo;

struct SeqList;//结构体声明--用于两个头文件要相互引用的情况

typedef struct SeqList Contact;//重新命名,便于理解与逻辑分析

//通讯录初始化
void ContactInit(Contact* con);

//通讯录销毁
void ContactDestory(Contact* con);

//通讯录添加数据
void ContactAdd(Contact* con);

//通讯录删除数据
void ContactDel(Contact* con);

//通讯录修改数据
void ContactModify(Contact* con);

//通讯录查找
void ContactFind(Contact* con);

//打印通讯录数据
void ContactShow(Contact* con);

//保存数据
int SaveContact(Contact* con);

//读取数据
int LoadContact(Contact* con);

 通讯录c文件(Contact.c)

#include "SeqList.h"
#include "Contact.h"


//通讯录初始化
void ContactInit(Contact* con)
{
	SLInit(con);//顺序表初始化的调用
}

//通讯录销毁
void ContactDestory(Contact* con)
{
	SLDestory(con);//顺序表销毁的调用
}

//通讯录添加数据
void ContactAdd(Contact* con)
{
	//获取联系人信息
	peoInfo info;
	printf("请输入要添加的联系人姓名:");
	gets_s(info.name);
	printf("请输入要添加的联系人性别:");
	gets_s(info.gender);
	printf("请输入要添加的联系人年龄:");
	scanf_s("%d", &info.age);
	getchar();//读取缓冲区的回车
	printf("请输入要添加的联系人电话:");
	gets_s(info.tel);
	printf("请输入要添加的联系人地址:");
	gets_s(info.addr);
	printf("请输入要添加的联系人生日:");
	gets_s(info.birthday);

	//将数据存入通讯录中
	SLPushBack(con, info);//顺序表尾插的调用
}

//数据查找--按名字查找
int FindByName(Contact* con, char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

//通讯录删除数据
void ContactDel(Contact* con)
{
	//查找数据
	char name[NAME_MAX];
	printf("请输入要删除联系人的姓名:");
	gets_s(name);

	int find = FindByName(con, name);//通讯录按名字查找
	if (find < 0)
	{
		printf("该用户不存在!\n");
		return;
	}
	//删除
	SLErase(con, find);//顺序表指定位置删的调用
	printf("删除成功!\n");
}

//通讯录修改数据
void ContactModify(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要修改联系人的姓名:");
	gets_s(name);

	int find = FindByName(con, name);//通讯录按名字查找
	if (find < 0)
	{
		printf("该用户不存在!\n");
		return;
	}
	//修改
	printf("请输入要添加的联系人姓名:");
	gets_s(con->arr[find].name);
	printf("请输入要添加的联系人性别:");
	gets_s(con->arr[find].gender);
	printf("请输入要添加的联系人年龄:");
	scanf_s("%d", &con->arr[find].age);
	getchar();//读取缓冲区的回车
	printf("请输入要添加的联系人电话:");
	gets_s(con->arr[find].tel);
	printf("请输入要添加的联系人地址:");
	gets_s(con->arr[find].addr);
	printf("请输入要添加的联系人生日:");
	gets_s(con->arr[find].birthday);

	printf("修改成功!\n");
}

//通讯录查找
void ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名:");
	gets_s(name);

	int find = FindByName(con, name);//通讯录按名字查找
	if (find < 0)
	{
		printf("该用户不存在!\n");
		return;
	}
	//打印用户信息
	printf("\n%-6s %-6s %-6s %-13s %-10s %-10s\n", "姓名", "性别", "年龄", "电话", "地址","生日");
	printf("%-6s %-6s %-6d %-13s %-10s %-10s\n\n",
			con->arr[find].name,
			con->arr[find].gender,
			con->arr[find].age,
			con->arr[find].tel,
			con->arr[find].addr,
			con->arr[find].birthday);
}

//打印通讯录数据
void ContactShow(Contact* con)
{
	printf("\n%-6s %-6s %-6s %-13s %-10s %-10s\n", "姓名","性别", "年龄", "电话", "地址", "生日");
	for (int i = 0; i < con->size; i++)
	{
		printf("%-6s %-6s %-6d %-13s %-10s %-10s\n",
				con->arr[i].name,
				con->arr[i].gender,
				con->arr[i].age,
				con->arr[i].tel,
				con->arr[i].addr,
				con->arr[i].birthday);
	}
	printf("\n");
}

4,文件保存与读取(FILE)

文件的两个函数通常定义在通讯录文件中(Contact.h和Contact.c)

文件保存函数        int SaveContact(Contact* con)

//保存数据
int SaveContact(Contact* con)
{
	FILE* pf = fopen("Contact.txt", "wb");//二进制写打开
	//对打开是否成功的判断
	if (pf == NULL)
	{
		perror("SaveContact");
		return 1;
	}
	//将通讯录数据依次保存至文件中
	for (int i = 0; i < con->size; i++)
	{
		fwrite(con->arr + i, sizeof(peoInfo), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 文件读取函数        int LoadContact(Contact* con)

//读取数据
int LoadContact(Contact* con)
{
	FILE* pf = fopen("Contact.txt", "rb");//二进制读打开
	//对打开是否成功的判断
	if (pf == NULL)
	{
		perror("LoadContact");
		return 1;
	}
	//将文件中保存的内容依次下载进通讯录中
	peoInfo tmp = { 0 };
	int i = 0;
	while (fread(&tmp, sizeof(peoInfo), 1, pf))
	{
		SLPushBack(con, tmp);
		i++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

三:总体代码整理

main.c文件

#ifndef _SEQLIST_H
#define _SEQLIST_H

#include "SeqList.h"

#endif

//菜单
void menu(Contact* con)
{
	printf("***************************************************\n");
	printf("********************  通讯录  *********************\n");
	printf("************1.添加联系人   2.删除联系人************\n");
	printf("************3.修改联系人   4.查找联系人************\n");
	printf("************5.展示联系人   0.退出通讯录************\n");
	printf("************    联系人数量:%d/%d  ****************\n",con->size,con->capacity);
	printf("***************************************************\n");
}


//主函数逻辑
int main()
{
	int op = -1;//操作选项变量
	Contact con;//创建通讯录变量
	ContactInit(&con);//初始化通讯录
	LoadContact(&con);//下载文件内容至通讯录

	do {
		menu(&con);//打印菜单
		printf("请选择您的操作:");
		scanf_s("%d", &op);//保存操作
		getchar();//消除缓冲区的回车字符

		//对应op执行操作
		switch (op)
		{
		case 1:
			ContactAdd(&con);//添加联系人
			break;
		case 2:
			ContactDel(&con);//删除联系人
			break;
		case 3:
			ContactModify(&con);//修改联系人数据
			break;
		case 4:
			ContactFind(&con);//查找联系人
			break;
		case 5:
			ContactShow(&con);//展示所有联系人
			break;
		case 0:
			printf("推出通讯录......\n");//退出
			break;
		default:
			printf("不存在此操作!\n");//操作不存在
			break;
		}
	} while (op);//op==0即选择退出操作时退出循环

	char ch;//创建文件是否保存的变量
	//是否保存此次对通讯录的修改
	do {
		printf("是否保存此次更改(Y/N)(y/n):");
		ch = getchar();//读取选项
		switch (ch)
		{
		case 'y':case 'Y':
			SaveContact(&con);//把通讯录内容保存到文件中
			printf("保存成功!\n");
			break;
		case 'n':case 'N':
			printf("未保存!\n");
			break;
		default:
			printf("没有此选项!请重新选择:\n");
		}

	} while (ch != 'n' && ch != 'N' && ch != 'y' && ch != 'Y');
	
	ContactDestory(&con);//销毁通讯录

	printf("按回车键推出程序!");

	getchar();//输入ch后的 回车字符
	getchar();//再次输入回车后退出程序

	return 0;
}

 SeqList.h文件

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "Contact.h"


//#define N 100
//
//静态顺序表
//struct SeqList_Static
//{
//	int arr[N];
//	int size;
//};

typedef peoInfo SLDateType;//对联系人结构体的声明

//动态顺序表
typedef struct SeqList
{
	SLDateType* arr;//数组--底层逻辑是数组的连续性--保存联系人数据
	int size;//有效数据个数
	int capacity;//开辟的空间大小
}SL;

//顺序表初始化
void SLInit(SL* ps);

//顺序表销毁
void SLDestory(SL* ps);

//头部插入删除/尾部插入删除
void SLPushBack(SL* ps, SLDateType x);//尾插
void SLPushFront(SL* ps, SLDateType x);//头插
void SLPopBack(SL* ps);//尾删
void SLPopFront(SL* ps);//头删

//指定位置的插入删除
void SLInsert(SL* ps, int pos, SLDateType x);//插入
void SLErase(SL* ps, int pos);//删除

//顺序表的查找
int SLFind(SL* ps, SLDateType x);

//打印顺序表
void SLPrrintf(SL s);

 SeqList.c文件

#ifndef _SEQLIST_H
#define _SEQLIST_H

#include "SeqList.h"

#endif

//顺序表初始化
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

//顺序表销毁
void SLDestory(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

//判断空间够不够--扩容
void SLcheckCapacity(SL* ps)
{
	//插入前判断空间够不够
	if (ps->capacity == ps->size)
	{
		//申请空间--增容--realloc
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//三目操作符
		SLDateType* tmp = (SLDateType*)realloc(ps->arr, newCapacity * sizeof(SLDateType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}

//尾插
void SLPushBack(SL* ps, SLDateType x)
{
	//断言
	assert(ps);
	//插入前判断空间够不够
	SLcheckCapacity(ps);
	//尾部插入x
	ps->arr[ps->size++] = x;
}

//头插
void SLPushFront(SL* ps, SLDateType x)
{
	//断言
	assert(ps);
	//插入前判断空间够不够
	SLcheckCapacity(ps);
	//移动数据位置--后移一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	//头部插入x
	ps->arr[0] = x;
	ps->size++;
}

//尾删
void SLPopBack(SL* ps)
{
	//断言
	assert(ps);//ps是否为NULL
	assert(ps->size);//size是否为0
	//尾部删除
	--ps->size;
}

//头删
void SLPopFront(SL* ps)
{
	//断言
	assert(ps);//ps是否为NULL
	assert(ps->size);//size是否为0
	//头部删除--所有数据向前移动一位
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	--ps->size;
}

//在指定位置之前插入
void SLInsert(SL* ps, int pos, SLDateType x)
{
	//断言
	assert(ps);//ps是否为NULL
	assert(pos >= 0 && pos <= ps->size);
	//插入前判断空间够不够
	SLcheckCapacity(ps);
	//插入
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}

//指定位置删除
void SLErase(SL* ps, int pos)
{
	//断言
	assert(ps);//ps是否为NULL
	assert(pos >= 0 && pos < ps->size);
	//shanchu
	for (int i = pos; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

//顺序表的查找
//int SLFind(SL* ps, SLDateType x)
//{
//	//断言
//	assert(ps);//ps是否为NULL
//	for (int i = 0; i < ps->size; i++)
//	{
//		if (ps->arr[i] == x)
//		{
//			return i;
//		}
//	}
//	return -1;
//}

//打印顺序表
void SLPrrintf(SL s)
{
	if (s.size)
	{
		for (int i = 0; i < s.size; i++)
		{
			printf("%d ", s.arr[i]);
		}
	}
	else
	{
		printf("无有效数据:size=0");
	}
	printf("\n");
}

 Contact.h文件

#pragma once

#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100

//联系人数据结构
typedef struct personInfo
{
	char name[NAME_MAX];//姓名
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//地址
	char birthday[20];//生日
}peoInfo;

struct SeqList;//结构体声明--用于两个头文件要相互引用的情况

typedef struct SeqList Contact;//重新命名,便于理解与逻辑分析

//通讯录初始化
void ContactInit(Contact* con);

//通讯录销毁
void ContactDestory(Contact* con);

//通讯录添加数据
void ContactAdd(Contact* con);

//通讯录删除数据
void ContactDel(Contact* con);

//通讯录修改数据
void ContactModify(Contact* con);

//通讯录查找
void ContactFind(Contact* con);

//打印通讯录数据
void ContactShow(Contact* con);

//保存数据
int SaveContact(Contact* con);

//读取数据
int LoadContact(Contact* con);

Contact.c文件

#include "SeqList.h"
#include "Contact.h"


//通讯录初始化
void ContactInit(Contact* con)
{
	SLInit(con);//顺序表初始化的调用
}

//通讯录销毁
void ContactDestory(Contact* con)
{
	SLDestory(con);//顺序表销毁的调用
}

//通讯录添加数据
void ContactAdd(Contact* con)
{
	//获取联系人信息
	peoInfo info;
	printf("请输入要添加的联系人姓名:");
	gets_s(info.name);
	printf("请输入要添加的联系人性别:");
	gets_s(info.gender);
	printf("请输入要添加的联系人年龄:");
	scanf_s("%d", &info.age);
	getchar();//读取缓冲区的回车
	printf("请输入要添加的联系人电话:");
	gets_s(info.tel);
	printf("请输入要添加的联系人地址:");
	gets_s(info.addr);
	printf("请输入要添加的联系人生日:");
	gets_s(info.birthday);

	//将数据存入通讯录中
	SLPushBack(con, info);//顺序表尾插的调用
}

//数据查找--按名字查找
int FindByName(Contact* con, char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

//通讯录删除数据
void ContactDel(Contact* con)
{
	//查找数据
	char name[NAME_MAX];
	printf("请输入要删除联系人的姓名:");
	gets_s(name);

	int find = FindByName(con, name);//通讯录按名字查找
	if (find < 0)
	{
		printf("该用户不存在!\n");
		return;
	}
	//删除
	SLErase(con, find);//顺序表指定位置删的调用
	printf("删除成功!\n");
}

//通讯录修改数据
void ContactModify(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要修改联系人的姓名:");
	gets_s(name);

	int find = FindByName(con, name);//通讯录按名字查找
	if (find < 0)
	{
		printf("该用户不存在!\n");
		return;
	}
	//修改
	printf("请输入要添加的联系人姓名:");
	gets_s(con->arr[find].name);
	printf("请输入要添加的联系人性别:");
	gets_s(con->arr[find].gender);
	printf("请输入要添加的联系人年龄:");
	scanf_s("%d", &con->arr[find].age);
	getchar();//读取缓冲区的回车
	printf("请输入要添加的联系人电话:");
	gets_s(con->arr[find].tel);
	printf("请输入要添加的联系人地址:");
	gets_s(con->arr[find].addr);
	printf("请输入要添加的联系人生日:");
	gets_s(con->arr[find].birthday);

	printf("修改成功!\n");
}

//通讯录查找
void ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名:");
	gets_s(name);

	int find = FindByName(con, name);//通讯录按名字查找
	if (find < 0)
	{
		printf("该用户不存在!\n");
		return;
	}
	//打印用户信息
	printf("\n%-6s %-6s %-6s %-13s %-10s %-10s\n", "姓名", "性别", "年龄", "电话", "地址","生日");
	printf("%-6s %-6s %-6d %-13s %-10s %-10s\n\n",
			con->arr[find].name,
			con->arr[find].gender,
			con->arr[find].age,
			con->arr[find].tel,
			con->arr[find].addr,
			con->arr[find].birthday);
}

//打印通讯录数据
void ContactShow(Contact* con)
{
	printf("\n%-6s %-6s %-6s %-13s %-10s %-10s\n", "姓名","性别", "年龄", "电话", "地址", "生日");
	for (int i = 0; i < con->size; i++)
	{
		printf("%-6s %-6s %-6d %-13s %-10s %-10s\n",
				con->arr[i].name,
				con->arr[i].gender,
				con->arr[i].age,
				con->arr[i].tel,
				con->arr[i].addr,
				con->arr[i].birthday);
	}
	printf("\n");
}

//保存数据
int SaveContact(Contact* con)
{
	FILE* pf = fopen("Contact.txt", "wb");//二进制写打开
	//对打开是否成功的判断
	if (pf == NULL)
	{
		perror("SaveContact");
		return 1;
	}
	//将通讯录数据依次保存至文件中
	for (int i = 0; i < con->size; i++)
	{
		fwrite(con->arr + i, sizeof(peoInfo), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

//读取数据
int LoadContact(Contact* con)
{
	FILE* pf = fopen("Contact.txt", "rb");//二进制读打开
	//对打开是否成功的判断
	if (pf == NULL)
	{
		perror("LoadContact");
		return 1;
	}
	//将文件中保存的内容依次下载进通讯录中
	peoInfo tmp = { 0 };
	int i = 0;
	while (fread(&tmp, sizeof(peoInfo), 1, pf))
	{
		SLPushBack(con, tmp);
		i++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嚴老三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值