Address book version 2.0 (file saving version)

Keywords: C

Preface: a previous blog Address book dynamic version In, I have completed an address book that can dynamically increase the capacity. When the address book runs, you can add and delete data to the address book. At this time, the data is stored in memory, but when the program exits, we will find that the data in the address book does not exist. When the address book program runs next time, the data will have to be re entered, Such an address book will inevitably have a lot of trouble. Therefore, in order to solve this problem, this time we will bring the address book version 2.0, that is, the version that can be saved in a file. Next, let's have a look!

stay One time can learn the file operation! Introduced many file operations, which will be used to optimize our address book this time.

Save address book data to file

In order to ensure that the address book still has the data entered for the first time when it is opened for the second time, we need to save the data in the address book to the file before closing the address book for the first time, so we define a function SaveContact to save the data to the file, which is defined as:

void SaveContact(Contact* pc)
{
	FILE* pf = fopen("Contact.dat", "w");//Create and open a file as a write
	if (pf == NULL)
	{
		perror("Contact.dat");
		return;
	}
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);//Saving data to a file using a loop
	}
	fclose(pf);
	pf = NULL;
}

Load data into address book

When we save the data of the last address book, the next time we use the address book, we should first load the data saved in the last address book into the address book, so we need to adjust the function of initializing the address book accordingly, that is, load the data first during initialization, and the defined function is LoadContact, It should also be noted that during data loading, if the loaded data capacity is greater than the original capacity, the loading will fail. In order to avoid this situation, it is necessary to judge whether the capacity needs to be expanded before loading, so the function CheckCapacity is defined to judge.
The two functions are as follows:

void CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (ADD_CAP + pc->capacity) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += ADD_CAP;
			printf("Successful capacity increase!\n");
		}
		else
		{
			printf("Capacity increase failed\n");
			return;
		}
	}
}
void LoadContact(Contact * pc)
{
	FILE* pf = fopen("Contact.dat", "r");//Open file read
	if (pf == NULL)
	{
		perror("Contact.dat");
		return;
	}
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))//Load one data into the address book at a time when the data in the address book is added
	                                            //After loading and playing, the fread function will return 0. At this time, the loop will end naturally
	{
		CheckCapacity(pc);//Before loading, first judge whether to expand the capacity
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	fclose(pf);
	pf = NULL;
}

Code overview

The same is divided into three documents as follows:
contact.h

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

#define MAX_NAME 20
#define SEX 10
#define MAX_ADDR 100
#define MAX_TELE 12
#define MAX_SZ 3
#define ADD_CAP 2
#define MAX 1000

typedef struct PeoInfo
{
	char name[MAX_NAME];
	char sex[SEX];
	int  age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];	
} PeoInfo;  //Redefine for ease of use, the same below

typedef struct Contact
{
	PeoInfo* data;
	int sz;
	int capacity;
}Contact;  //redefinition

void InitContact(Contact* pc);  //Initialize address book

void AddContact(Contact* pc);  //Add a contact 

void PrintContact(const Contact* pc);  //Print address book

void DelContact(Contact* pc);  //Delete Contact 

void SearchContact(Contact* pc);  //find contact 

void ModifyContact(Contact* pc);  //Modify contact

void DestoryContact(Contact* pc);  //Destroy address book

void SaveContact(Contact* pc);  //Save address book

void LoadContact(Contact* pc);  //Load address book

void CheckCapacity(Contact* pc);   //Determine address book

test.c

#include"contact.h" / / reference header file
void menu()
{
	printf("***************************\n");
	printf("***   1.Add     2.Del   ***\n");
	printf("***   3.Search  4.Modify***\n");
	printf("***        5.Print      ***\n");
	printf("***        0.Exit       ***\n");
	printf("***************************\n");
}

enum Option //Define the name of each function as a member of an enumeration type to make it more recognizable
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	PRINT,
};
 
int main()
{
	Contact con;
	InitContact(&con);
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		    case ADD:
				AddContact(&con);//Add a Contact 
				break;
			case DEL:
				DelContact(&con);//Delete Contact 
				break;
			case SEARCH:
				SearchContact(&con);//find contact 
				break;
			case MODIFY:
				ModifyContact(&con);//Modify contact
				break;
			case PRINT:
				PrintContact(&con);//show address book
				break;
			case EXIT:
			    SaveContact(&con);//Save the data in the address book before destroying it
			    
				DestoryContact(&con);//Destroy address book
				printf("Exit address book\n");
				break;
			default:
				printf("Selection error, please re select:");
				break;
		}
	} while (input);
	return 0;
}

contact.c

#include"contact.h"
void CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (ADD_CAP + pc->capacity) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += ADD_CAP;
			printf("Successful capacity increase!\n");
		}
		else
		{
			printf("Capacity increase failed\n");
			return;
		}
	}
}

void LoadContact(Contact * pc)
{
	FILE* pf = fopen("Contact.dat", "r");
	if (pf == NULL)
	{
		perror("Contact.dat");
		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(MAX_SZ * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->sz = 0;
	pc->capacity = MAX_SZ;
	LoadContact(pc);
}

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


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

void AddContact(Contact* pc)
{
	CheckCapacity(pc);
	
	printf("Please enter your name:>");
	scanf("%s", pc->data[pc->sz].name);
	printf("Please enter gender:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("Please enter age:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("Please enter phone number:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("Please enter the address:>");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("Increase success!\n");
}

void PrintContact(const Contact* pc)
{
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\t\n", "full name", "Gender", "Age", "Telephone", "address");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\t\n",
			pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].age,
			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(name, (pc->data[i]).name) == 0)
			return i;
	}
	return -1;
}

void DelContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	printf("Please enter the contact to delete:>");
	scanf("%s", name);
	int x = FindContact(pc, name);
	if (x < 0)
	{
		printf("No contacts found\n");
	}
	else
	{
		int i = 0;
		for (i = x; x < pc->sz - 1; x++)
		{
			pc->data[x] = pc->data[x + 1];
		}
		pc->sz--;
		printf("Delete succeeded!\n");
	}
}

void SearchContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	printf("Please enter the contact you want to find:>");
	scanf("%s", name);
	int x = FindContact(pc, name);
	if (x < 0)
	{
		printf("No contacts found\n");
	}
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\t\n", "full name", "Gender", "Age", "Telephone", "address");
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\t\n",
			pc->data[x].name,
			pc->data[x].sex,
			pc->data[x].age,
			pc->data[x].tele,
			pc->data[x].addr);
	}
}

void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	printf("Please enter the contact to modify:>");
	scanf("%s", name);
	int x = FindContact(pc, name);
	if (x < 0)
	{
		printf("No contacts found\n");
	}
	else
	{
		printf("Please enter your name:>");
		scanf("%s", pc->data[x].name);
		printf("Please enter gender:>");
		scanf("%s", pc->data[x].sex);
		printf("Please enter age:>");
		scanf("%d", &(pc->data[x].age));
		printf("Please enter phone number:>");
		scanf("%s", pc->data[x].tele);
		printf("Please enter the address:>");
		scanf("%s", pc->data[x].addr);
		printf("Modified successfully!\n");
	}
}

Posted by TJMAudio on Sun, 19 Sep 2021 07:12:25 -0700