C language - address book (can save address book information)

foreword

After writing the address book program, when the address book is running, you can add or delete data in the address book. At this time, the data is stored in the memory. When the program exits, the data in the address book will naturally disappear. It exists, and when the address book program is run next time, the data has to be re-entered. It is very uncomfortable to use such an address book.

Since it is an address book, the information should be recorded. Only when you choose to delete the data, the data will no longer exist. This involves the problem of data persistence. Generally, the methods of data persistence include storing data in disk files and storing them in databases.

Using files can store data directly on the hard disk of the computer, achieving data persistence.

Save the information in the address book

The address book information needs to be saved when the address book is exited. Note that the address book information should be saved to a file before destroying the address book. The information preservation of the address book is to save the information by writing the address book information into the file through the file operation.

void SaveContact(Contact* pc)
{
    
    
	FILE* pf = fopen("contact.dat", "w");
	if (pf == NULL)
	{
    
    
		perror("SaveContact");
		return;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
    
    
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}

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

Contact information loading

Before adding, deleting, checking and modifying the address book, the address book has to load the information stored before, so only when the address book is initialized, the information is read from the file to the address book to complete the information loading process. Information loading When reading the file to stop (I don’t know how much information the file has), then you need to use the fread function, judge by the return value of the fread function, if it is less than the actual number of counts to be read, it means this reading It is impossible to read the data after reading fread. Read data from the file and put it in the address book. When putting data into the address book, you need to pay attention that the address book can store up to DEFAULT_SZ data when the address book is just initialized. The number of data loaded may be larger than the capacity of the address book just initialized. . At this time, it is necessary to determine whether to increase the capacity. After judging the capacity increase, add the information of the person read from the file to the newly initialized address book, and then increase the number of valid information in the current address book by one.

void CheckCapacity(Contact* pc)
{
    
    
	if (pc->sz == pc->capacity)
	{
    
    
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
    
    
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("增容成功\n");
		}
		else
		{
    
    
			perror("AddContact");
			printf("增加联系人失败\n");
			return;
		}
	}
}

void LoadContact(Contact* pc)
{
    
    
	FILE* pf = fopen("contact.dat", "r");
	if (pf == NULL)
	{
    
    
		perror("LoadContact");
		return;
	}
	//读文件
	PeoInfo tmp = {
    
     0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))
	{
    
    
		//是否需要增容
		CheckCapacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}

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


//初始化
void InitContact(Contact* pc)
{
    
    
	pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
    
    
		perror("InitContact");
		return;
	}
	pc->sz = 0;//初始化后默认是0
	pc->capacity = DEFAULT_SZ;

	//加载文件
	LoadContact(pc);
}

The overall code of the address book (which can save address book information)

contact.h

#pragma once


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

#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30


#define MAX 1000

#define DEFAULT_SZ 3
#define INC_SZ 2


//类型的定义
typedef struct PeoInfo
{
    
    
	char name[MAX_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;



//通讯录
typedef struct Contact
{
    
    
	PeoInfo* data;//指向动态申请的空间,用来存放联系人的信息
	int sz;//记录的是当前通讯录中有效信息的个数
	int capacity;//记录当前通讯录的最大容量
}Contact;


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

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

//打印联系人信息
void PrintContact(const Contact* pc);

//删除联系人的信息
void DelContact(Contact* pc);

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

//修改指定联系人
void ModifyContact(Contact* pc);

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

//排序通讯录
void SortContact(struct Contact* pc);

//保存通讯录信息到文件
void SaveContact(Contact* pc);

//加载文件内容到通讯录
void LoadContact(Contact* pc);

//检测增容的问题
void CheckCapacity(Contact* pc);



contact.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"


//初始化
void InitContact(Contact* pc)
{
    
    
	pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
    
    
		perror("InitContact");
		return;
	}
	pc->sz = 0;//初始化后默认是0
	pc->capacity = DEFAULT_SZ;

	//加载文件
	LoadContact(pc);
}

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


void SaveContact(Contact* pc)
{
    
    
	FILE* pf = fopen("contact.dat", "w");
	if (pf == NULL)
	{
    
    
		perror("SaveContact");
		return;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
    
    
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}

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

void LoadContact(Contact* pc)
{
    
    
	FILE* pf = fopen("contact.dat", "r");
	if (pf == NULL)
	{
    
    
		perror("LoadContact");
		return;
	}
	//读文件
	PeoInfo tmp = {
    
     0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))
	{
    
    
		//是否需要增容
		CheckCapacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}

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


void CheckCapacity(Contact* pc)
{
    
    
	if (pc->sz == pc->capacity)
	{
    
    
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
    
    
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("增容成功\n");
		}
		else
		{
    
    
			perror("AddContact");
			printf("增加联系人失败\n");
			return;
		}
	}
}

//增加联系人
void AddContact(Contact* pc)
{
    
    
	//考虑增容
	CheckCapacity(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].tele);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->sz].addr);

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



void PrintContact(const Contact* pc)
{
    
    
	int i = 0;
	//打印标题
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
	//打印数据
	for (i = 0; i < pc->sz; i++)
	{
    
    
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}

static int FindByName(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 DelContact(Contact* pc)
{
    
    
	char name[MAX_NAME] = {
    
     0 };

	if (pc->sz == 0)
	{
    
    
		printf("通讯录为空,无需删除\n");
		return;
	}
	printf("请输入要删除人的名字:>");
	scanf("%s", name);

	//1. 查找要删除的人
	//有/没有
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
    
    
		printf("要删除的人不存在\n");
		return;
	}
	//2. 删除
	int i = 0;
	for (i = pos; i < pc->sz - 1; i++)
	{
    
    
		pc->data[i] = pc->data[i + 1];
	}

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


void SearchContact(Contact* pc)
{
    
    
	char name[MAX_NAME] = {
    
     0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", name);

	int pos = FindByName(pc, name);
	if (pos == -1)
	{
    
    
		printf("要查找的人不存在\n");
		return;
	}
	else
	{
    
    
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
		//打印数据
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",
			pc->data[pos].name,
			pc->data[pos].age,
			pc->data[pos].sex,
			pc->data[pos].tele,
			pc->data[pos].addr);
	}
}


void ModifyContact(Contact* pc)
{
    
    
	char name[MAX_NAME] = {
    
     0 };
	printf("请输入要修改人的名字:>");
	scanf("%s", name);

	int pos = FindByName(pc, name);
	if (pos == -1)
	{
    
    
		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].tele);
		printf("请输入地址:>");
		scanf("%s", pc->data[pos].addr);

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



//自定义比较函数
static int CmpByName(const void* e1, const void* e2)
{
    
    
	return strcmp((const char*)e1, (const char*)e2);
}


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

test.c

#define _CRT_SECURE_NO_WARNINGS 1



//当通讯录退出的时候,把信息写到文件
//当通讯录初始化的时候,加载文件的信息到通讯录中



#include "contact.h"

void menu()
{
    
    
	printf("********************************\n");
	printf("******  1. add    2. del  ******\n");
	printf("******  3. search 4. modify*****\n");
	printf("******  5. sort   6. print *****\n");
	printf("******  0. exit            *****\n");
	printf("********************************\n");
}

enum Option
{
    
    
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};

int main()
{
    
    
	int input = 0;
	//创建通讯录
	Contact con;//通讯录
	//初始化通讯录
	//给data申请一块连续的空间再堆区上
	//sz=0
	//capacity 初始化为当前的最大的容量
	InitContact(&con);

	do
	{
    
    
		menu();
		printf("请选择:>");
		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 SORT:
			SortContact(&con);
			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT:
			//保存信息到文件
			SaveContact(&con);
			//销毁通讯录
			DestoryContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);

	return 0;
}


Guess you like

Origin blog.csdn.net/AI_ELF/article/details/130989285