【娱乐大闯关】C语言实现通讯录(文件版)

文章目录

  • 一、TXL.h
    • 1、头文件
    • 2、所需常量
    • 3、所需存放的个人信息
    • 4、通讯录需存放的内容
    • 5、创建选择功能
    • 6、所需函数声明
  • 二、Fun_txl.c
    • 一、初始化通讯录
      • 加载本地数据
      • 容量检查
    • 二、功能一:添加联系人
    • 三、功能二:删除不需要的联系人
      • 按姓名查找联系人位置
    • 四、功能三:修改联系人的信息
      • 具体信息修改函数
    • 五、功能四:查找联系人
    • 六、功能五:显示所有联系人信息
      • 排序函数
    • 七、功能六:退出操作
      • 通讯录销毁函数
      • 保存数据函数
  • 三、Main_txl.c
    • 创建通讯录
    • 一、主函数
    • 二、选择系统
  • 四、执行结果

在这里插入图片描述

该通讯录采用文件存储方式保存联系人信息,主要功能有增加联系人、删除联系人、查找联系人、修改联系人信息、显示五大功能,外加排序、保存两大副功能!


创建txl.h放头文件等需共用的代码,创建txlhs.c放所需的函数代码,创建txl.c进行测试


本程序未解决:联系人姓名重复问题与联系人信息重复问题

一、TXL.h

1、头文件

#include 
#include 
#include 

2、所需常量

#define MAX_NAME 20
#define MAX_TELE 12
#define MAX_ADDR 30
#define CP_SZ 5//通讯录开始容量为5

3、所需存放的个人信息

只需存放姓名、电话、住址即可,若要存其他可增加!

typedef struct Info {
	char name[MAX_NAME];//姓名
	char tele[MAX_TELE];//电话
	char addr[MAX_ADDR];//住址
}Info;

4、通讯录需存放的内容

typedef struct Contact {
	Info* data;//存放信息
	int size;//记录当前已有的通讯录人数
	int capacity;//记录当前通讯录的容量
}Contact;

5、创建选择功能

利用枚举功能,创建通讯录内部选择键,方便程序员写代码!

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

6、所需函数声明

实现功能:增、删、改、查、显示、销毁、初始化

void InitContact(Contact* p);//初始化通讯录
void AddContact(Contact* p);//添加联系人
void DelContact(Contact* p);//删除指定联系人
void SearchContact(const Contact* p);//查找联系人
void ModifyContact(Contact* p);//修改联系人信息
void ShowContact(Contact* p);//显示通讯录信息
void DestroyContact(Contact* p);//销毁通讯录
void slect();//主菜单选择函数

二、Fun_txl.c

一、初始化通讯录

通讯录创建后我们得初始化通讯录:开辟动态存储空间、将通讯录已有人数设置为0,、容量初始化为5个(可在头文件中更改),并调用加载本地数据函数LoadContact(),加载本地数据到通讯录中!

void InitContact(Contact* p) {
	p->data = (Info*)malloc(CP_SZ * sizeof(Info));
	if (p->data == NULL) {
		perror("InitContact"); system("pause"); return;
	}
	p->size = 0;
	p->capacity = CP_SZ;
	LoadContact(p);
}

加载本地数据

将本地文件中的数据添加到通讯录中,添加之前调用容量检查函数CheckCapacity(),检查容量是否足够,若不够需增容,再写入!

void LoadContact(Contact *p) {
	Info temp = { 0 };
	FILE* fpRead = fopen("contact.dat", "rb");
	if (fpRead == NULL) {
		puts("加载数据失败!");
		perror("contact.dat"); system("pause"); return;
	}
	while (fread(&temp, sizeof(Info), 1, fpRead)) {
		CheckCapacity(p);
		p->data[p->size] = temp;
		p->size++;
	}
	fclose(fpRead);
	fpRead = NULL;
}

容量检查

检查通讯录中已有人数size与容量capacity是否相等;若相等,则需开辟空间(本人选择每次开辟5个),若不等,则什么也不做!

void CheckCapacity(Contact* p) {
	if (p->size == p->capacity) {
		Info* ptr = (Info*)realloc(p->data, (p->capacity + 5) * sizeof(Info));
		if (ptr != NULL) {
			p->data = ptr;
			p->capacity += 2; puts("增容成功!");
		}
		else {
			puts("增容失败!"); system("pause"); return;
		}
	}
}

二、功能一:添加联系人

添加前调用容量检查函数CheckCapacity(),检查通讯录的容量是否满足,再输入联系人信息,并将size增1(很重要)!

void AddContact(Contact* p) {
	CheckCapacity(p);
	printf("请输入姓名:> ");
	scanf("%s", p->data[p->size].name);
	printf("请输入电话:> ");
	scanf("%s", p->data[p->size].tele);
	printf("请输入地址:> ");
	scanf("%s", p->data[p->size].addr);
	p->size++;
	puts("添加成功!");
	system("pause");
}

三、功能二:删除不需要的联系人

删除前调用姓名查找函数FindByName(),找到需要删除的人的位置,再将其删除并将其后面的联系人补上来,再将size减少1个(很重要)!

void DelContact(Contact* p) {
	int pos = 0;
	int i = 0;
	char name[MAX_NAME];
	printf("请输入要删除人的姓名:> ");
	scanf("%s", name);
	pos = FindByName(p,name);
	if (pos==-1) {
		puts("查无此人!"); system("pause"); return;
	}
	else {
		for (i = pos; i < p->size - 1; i++)
			p->data[i] = p->data[i + 1];
		p->size--;
	}
	puts("删除成功!");
	system("pause");
}

按姓名查找联系人位置

遍历结构体成员,进行比较;若姓名一致,则返回该联系人的下标( i ),若找不到,则返回 (-1 )!

static int FindByName(const Contact* p, char name[MAX_NAME]) {
	int i = 0;
	for (i = 0; i < p->size; i++)
		if (strcmp(p->data[i].name, name) == 0)
			return i;
	return -1;
}

四、功能三:修改联系人的信息

调用姓名查找函数FindByName(),查找需要修改的人的位置,再调用具体修改函数DetModify(),修改具体信息!

void ModifyContact(Contact* p) {
	int pos = 0;
	char name[MAX_NAME];
	printf("请输入需要修改人的姓名:> ");
	scanf("%s", name);
	pos = FindByName(p, name);
	if (pos == -1) {
		puts("查无此人!"); system("pause"); return;
	}
	else {
		DetModify(p, pos);
	}
}

具体信息修改函数

采用菜单方式,选择需修改的具体内容!

void Mod_menu() {
	puts("*********************************");
	puts("*** 1、姓名  2、电话  3、地址 ***");
	puts("*** 4、放弃修改   5、修改完毕 ***");
	puts("*******************/*************");
}
void DetModify(Contact* p,int pos) {
	while (1) {
		system("cls");
		int input = 0;
		Mod_menu();
		puts("\n信息如下:");
		printf("%-20s\t%-20s\t%-20s\n", "名字", "电话", "地址");
		printf("%-20s\t%-20s\t%-20s\n", p->data[pos].name,
               p->data[pos].tele, p->data[pos].addr);
		printf("\n请选择;> ");
		scanf("%d", &input);
		switch (input) {
			case 1:printf("请输入姓名:> ");scanf("%s", p->data[pos].name);
				puts("姓名修改完毕!");	system("pause"); break;
			case 2:printf("请输入电话:> ");scanf("%s", p->data[pos].tele);
				puts("电话修改完毕!");	system("pause"); break;
			case 3:printf("请输入地址:> ");scanf("%s", p->data[pos].addr);
				puts("地址修改完毕!");	system("pause"); break;
			case 4:slect();
			case 5:slect();
			default:puts("选择错误,请重试!"); system("pause"); break;
		}
	}
}

五、功能四:查找联系人

调用姓名查找函数FindByName(),找到需查找的联系人的位置,再打印出来!

void SearchContact(const Contact* p) {
	int pos = 0;
	char name[MAX_NAME];
	printf("请输入需要查找人的姓名:> ");
	scanf("%s", name);
	pos = FindByName(p,name);
	if (pos == -1) {
		puts("查无此人!"); system("pause"); return;
	}
	else {
		printf("%-20s\t%-20s\t%-20s\n", "名字", "电话", "地址");
		printf("%-20s\t%-20s\t%-20s\n", p->data[pos].name, p->data[pos].tele, p->data[pos].addr);
	}
	puts("显示完毕!");
	system("pause");
}

六、功能五:显示所有联系人信息

显示之前调用排序函数SortContact(),将联系人排序,再打印出来!

void ShowContact(Contact* p) {
	SortContact(p);
	int i = 0;
	if (p->size == 0)
		puts("通讯录为空!");
	else {
		printf("%-20s\t%-20s\t%-20s\n", "名字", "电话", "地址");
		for (i = 0; i < p->size; i++) 
			printf("%-20s\t%-20s\t%-20s\n",p->data[i].name,p->data[i].tele,p->data[i].addr);
	}
	puts("显示完毕!");
	system("pause");
}

排序函数

按姓名先后顺序进行排序!

static void SortContact(Contact* p) {
	int i = 0, j = 0;
	Info name;
	for (i = 0; i < p->size; i++) {
		for (j = 0; j < p->size - 1; j++) {
			if (strcmp(p->data[j].name, p->data[j + 1].name) > 0) {
				name = p->data[j], p->data[j] = p->data[j + 1],
					p->data[j + 1] = name;
			}
		}
	}
}

七、功能六:退出操作

调用函数exit(0),退出程序之前,需调用通讯录销毁函数DestroyContact(),对开辟的动态内存空间进行释放!

exit(0);

通讯录销毁函数

销毁之前,需调用保存函数SaveContact(),将数据保存后再销毁!

void DestroyContact(Contact* p) {
	SaveContact(p);
	free(p->data);
	p->data = NULL;
	puts("通讯录销毁完毕!");
}

保存数据函数

将联系人信息,采用二进制的形式保存到电脑文件中。
保存之前,需在电脑文件中找到“txl.c”文件的位置处,添加一个“contact.dat”文件用于存放联系人信息!

static void SaveContact(Contact* p) {
	int i = 0;
	FILE* fpWrite = fopen("contact.dat", "wb");
	if (fpWrite == NULL) {
		puts("无法保存!");
		perror("contact.dat"); 
		system("pause"); return;
	}
	for (i = 0; i < p->size; i++)
		fwrite(&(p->data[i]), sizeof(Info), 1, fpWrite);
	fclose(fpWrite);
	fpWrite = NULL;
	puts("保存完毕!");
}

三、Main_txl.c

创建通讯录

Contact con;//con为通讯录,里面包含:data、size、capacity

一、主函数

int main() {
	//初始化通讯录
	InitContact(&con);
	slect();
	return 0;
}

二、选择系统

void menu() {
	puts("***************************************");
	puts("*** 1、添加 2、删除 3、查找 4、修改 ***");
	puts("*** 5、显示                 0、退出 ***");
	puts("***************************************");
	printf("请选择:> ");
}
void slect() {
	int input = 0;
	while (1) {
		system("cls");
		menu();
		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 Exit:DestroyContact(&con); puts("即将退出通讯录!");
				system("pause"); exit(0);
				break;
			default:puts("选择错误,请重试!"); system("pause"); break;
		}
	}
}

四、执行结果

添加联系人
【娱乐大闯关】C语言实现通讯录(文件版)_第1张图片
显示联系人
【娱乐大闯关】C语言实现通讯录(文件版)_第2张图片

你可能感兴趣的:(娱乐大闯关,c语言)