[C language] address book (file version)

Preface
We have completed the static version and dynamic version of the address book. Although the function is relatively complete, the previous address book lacks the ability to store contacts, so we have learned the operation and management of files. Here we use the previous article Let's complete this article with the knowledge of the article.
I put two links on the first two articles about the address book:
(1) Detailed explanation of the dynamic version of the address book
(2) Detailed explanation of the static version of the address book


1. Transformation

Transformation of InitContact (initialization) function

InitContact 函数The modification here is not only to initialize the address book, but also to load the contact information in the file into the address book. (The function of the LoadContact function is in the second part)

void IntiContact(Contact* pc)
{
    
    
	//默认通讯录储存三个人
	//容量不够了每次增加两个人
	PeoInfo* ptr = (PeoInfo*)malloc(sizeof(PeoInfo) * DEFAULT_SZ);
	if (ptr == NULL)
	{
    
    
		printf("初始化失败\n");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULT_SZ;
	pc->sz = 0;

	LoadContact(pc);//加载通讯录
}

2. Add function

1. Implementation of LoadContact (load address book) function

Here we useread onlyway to open abinary file:
If there is contact.txta file , the program will load the data in the file.
If there is no such file, an error will occur, and the cause of the error perror() 函数will be printed out.

没有  contact.txt  文件

insert image description here

有 contact.txt 文件并且储存了部分联系人的信息

insert image description here

void LoadContact(Contact* pc)
{
    
    
	//打开文件
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
    
    
		perror("LoadContact::fopen");
		return;
	}
	//操作文件
	PeoInfo ptr = {
    
     0 };
	while (fread(&ptr, sizeof(PeoInfo), 1 ,pf))
	{
    
    
		if (CheckContact(pc) == 0)
		{
    
    
			return;
		}
		pc->data[pc->sz++] = ptr;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}

2. Implementation of SaveConatct (Save Contacts) function

Here we usejust writeway to open abinary file:
If there is not contact.txta , then use fwrite() 函数to create a file in the file contact.txtand then perform file operations, if there is, directly perform file operations.

这里的文件夹中没有 contact.txt 文件

insert image description here

在使用完 fwrite()函数后就生成了一个 contact.txt 文件

insert image description here

void SaveConatct(const Contact* pc)
{
    
    
	//打开文件
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
    
    
		perror("SaveConatct::fopen");
		return;
	}
	//操作文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
    
    
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	printf("保存成功\n");
}

3. The overall realization of the address book

contact.h 文件的实现
#pragma once

#define MAX_NAME 20
#define MAX_SEX  5
#define MAX_TELE 13
#define MAX_ADDR 30

#define DEFAULT_SZ 3
#define INC_SZ 2


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


typedef struct PeoInfo
{
    
    
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;

typedef struct Contact
{
    
    
	PeoInfo* data;  //指向malloc函数申请的空间(此空间用于存储联系人的信息)
	int sz;         //记录当前通讯录联系人的个数
	int capacity;   //记录当前通讯录容量大小
}Contact;


//初始化通讯录
void IntiContact(Contact* pc);

//增加联系人
void AddContact(Contact* pc);

//打印通讯录
void ShowContact(const Contact* pc);

//删除联系人
void DulContact(Contact* pc);

//查找联系人
void SearchContact(const Contact* pc);

//修改联系人
void ModefyContact(Contact* pc);

//对通讯录进行排序
void SortContact(Contact* pc);

//销毁通讯录
void DestoryContact(Contact* pc);

//保存通讯录
void SaveConatct(const Contact* pc);

//加载通讯录
void LoadContact(Contact* pc);
contact.c 文件的实现
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4996)
#pragma warning(disable : 6031)

#include "contact.h"

//函数声明
int CheckContact(Contact* pc);

//加载通讯录
void LoadContact(Contact* pc)
{
    
    
	//打开文件
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
    
    
		perror("LoadContact::fopen");
		return;
	}
	//操作文件
	PeoInfo ptr = {
    
     0 };
	while (fread(&ptr, sizeof(PeoInfo), 1 ,pf))
	{
    
    
		if (CheckContact(pc) == 0)
		{
    
    
			return;
		}
		pc->data[pc->sz++] = ptr;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}

//初始化通讯录
void IntiContact(Contact* pc)
{
    
    
	//默认通讯录储存三个人
	//容量不够了每次增加两个人
	PeoInfo* ptr = (PeoInfo*)malloc(sizeof(PeoInfo) * DEFAULT_SZ);
	if (ptr == NULL)
	{
    
    
		printf("初始化失败\n");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULT_SZ;
	pc->sz = 0;

	LoadContact(pc);
}

void DestoryContact(Contact* pc)
{
    
    
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	printf("释放内存...\n");
}

int CheckContact(Contact* pc)
{
    
    
	//判断通讯录是否为满
	if (pc->sz == pc->capacity)
	{
    
    
		PeoInfo* ptr = realloc(pc->data, sizeof(PeoInfo) * (pc->capacity + INC_SZ));
		if (ptr == NULL)
		{
    
    
			printf("扩容失败\n");
			return 0;
		}
		pc->data = ptr;
		pc->capacity += INC_SZ;
		printf("扩容成功,当前容量为%d\n", pc->capacity);
		return 1;
	}
	return 1;
}


void AddContact(Contact* pc)
{
    
    
	if (CheckContact(pc) == 0)
	{
    
    
		return;
	}

	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].tele);
	printf("请输入需要添加联系人的地址:>");
	scanf("%s", pc->data[pc->sz].addr);

	pc->sz++;
}


void ShowContact(const Contact* pc)
{
    
    
	int i = 0;
	printf("%-20s %-4s %-5s %-13s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pc->sz; i++)
	{
    
    
		printf("%-20s %-4d %-5s %-13s %-30s\n",
			pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
	}
}

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

void SearchContact(const Contact* pc)
{
    
    
	char name[MAX_NAME] = {
    
     0 };
	printf("请输入要查找联系人的姓名\n");
	scanf("%s", name);

	int pos = FindContact(pc, name);

	if (pos == -1)
	{
    
    
		printf("通讯录中没有此人\n");
		return;
	}

	printf("%-20s %-4s %-5s %-13s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-20s %-4d %-5s %-13s %-30s\n",
		pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);
}

void DulContact(Contact* pc)
{
    
    
	char name[MAX_NAME] = {
    
     0 };
	if (pc->sz == 0)
	{
    
    
		printf("通讯录为空,无法删除\n");
		return;
	}

	printf("请输入要删除联系人的姓名\n");
	scanf("%s", name);

	int i = 0;
	int pos = FindContact(pc, name);

	if (pos == -1)
	{
    
    
		printf("通讯录中没有此人\n");
		return;
	}

	for (i = pos; i < pc->sz - 1; i++)
	{
    
    
		pc->data[i] = pc->data[i + 1];
	}

	pc->sz--;
	printf("删除成功\n");

}


void ModefyContact(Contact* pc)
{
    
    
	char name[MAX_NAME] = {
    
     0 };
	printf("请输入需要修改联系人的姓名\n");
	scanf("%s", name);

	int pos = FindContact(pc, name);

	if (pos == -1)
	{
    
    
		printf("通讯录中没有此人\n");
		return;
	}

	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].tele);
	printf("请输入需要修改联系人的地址:>");
	scanf("%s", pc->data[pos].addr);

}

int sort_by_name(const void* e1, const void* e2)
{
    
    
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}

void SortContact(Contact* pc)
{
    
    
	qsort(pc->data, pc->sz, sizeof(PeoInfo), sort_by_name);
	printf("排序成功\n");
}

//保存通讯录
void SaveConatct(const Contact* pc)
{
    
    
	//打开文件
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
    
    
		perror("SaveConatct::fopen");
		return;
	}
	//操作文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
    
    
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	printf("保存成功\n");
}
test.c 文件的实现
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4996)
#pragma warning(disable : 6031)

#include "contact.h"
//引用头文件,使得test.c文件能使用contact.h中引用的头文件、声明、定义的内容等

enum option
{
    
    
	EXIT,   //0  退出通讯录
	ADD,    //1  增减联系人
	DUL,    //2  删除联系人
	SEARCH, //3  查找联系人
	MODEFY, //4  修改联系人
	SHOW,   //5  打印通讯录
	SORT    //6  排序通讯录
};

void menu()
{
    
    
	printf("***************************************\n");
	printf("********   1.ADD     2.DUL     ********\n");
	printf("********   3.SEARCH  4.MODEFY  ********\n");
	printf("********   5.SHOW    6.SORT    ********\n");
	printf("********   0.Exit              ********\n");
	printf("***************************************\n");
}

int main()
{
    
    
	menu();
	Contact con = {
    
     0 };
	IntiContact(&con); //初始化通讯录
	int option = 0;
	do
	{
    
    
		printf("请选择:>");
		scanf("%d", &option);
		switch (option)
		{
    
    
			//case 1:
		case ADD: //增加联系人
			AddContact(&con);
			break;
			//case 2:
		case DUL://删除联系人
			DulContact(&con);
			break;
			//case 3:
		case SEARCH://查找联系人
			SearchContact(&con);
			break;
			//case 4:
		case MODEFY://修改联系人
			ModefyContact(&con);
			break;
			//case 5:
		case SHOW://打印通讯录
			ShowContact(&con);
			break;
			//case 6:
		case SORT://对通讯录进行排序
			SortContact(&con);
			break;
			//case 0:
		case EXIT:
			SaveConatct(&con);
			DestoryContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (option);
	return 0;
}

end

If you have any suggestions and questions, or if there are any mistakes, I hope everyone can mention them.
I hope everyone can make progress with me in the future! !
If this article is useful to you, I hope you can give me a little like!

Guess you like

Origin blog.csdn.net/qq_55401402/article/details/130278689