C language implementation of address book management system - dynamic memory allocation type

catalogue

1, Address book function requirement analysis:

2, File schema analysis:

3, Code, presented in modules:

3.1 main function:

3.2 # menu function:

3.3. Declaration part of enumeration type:

3.4 initialization of address book:

3.5. Add the contact information part of the address book:

3.6 ― part displaying contact information:

3.7 delete the part of contact information:

3.8 ― part of finding contact information:

3.9. Modify the part of contact information:

3.10. Sort the part of contact information:

3.11. Clear the part of all contact information:

3.12 destroy the part of the address book:

4, The code is rendered as a file:

4.1 test.c source file

        4.2 contact.c source file

        4.3 contact.h header file

1, Address book function requirement analysis:

In order to realize the address book management system, the following functions shall be ensured:

After the initial initialization, the address book can store the information of three people. When the space is full, add two more contact information. If it is not enough, add two contact information and each person's information each time

Including: name, age, gender, telephone, address, in addition, it is also realized: add person's information, delete person's information, modify specified person's information, find specified person's information, empty contact's information, and display

Display the contact information, sort the address book information, and destroy the address book.

2, File schema analysis:

1,test.c - module and main function interface used to test the address book.

2,contact.h - definition of types related to address book, declaration of functions, header files of library functions, etc

3,contact.c-function implementation

Finish writing contact h,contact. After C, reference both to test C) it can meet the requirements when used in.

3, Code, presented in modules:

3.1 main function:

int main()
{
	int input = 0;
	//When creating an address book, the structure type is defined in the header file, so the header file should be introduced,
	There are currently several elements in the address book:
	//int sz = 0;
	//Create address book
	Contact con; //con is the address book, which can also be initialized directly. However, in order to better reflect modularization, a function is encapsulated in the initialization address book.
	//If you want to initialize some of them to 0, you must use functions.

	//Initialize address book
	//Use malloc function to dynamically open up a continuous memory space on the heap, and put the address of the starting position of the space in the structure pointer variable data.
	//Initialize integer variable sz=0;
	//Initialize the integer variable capacity to the current maximum capacity
	InitContact(&con);//When initializing the address book, the content in the address book should be modified. If it is called by value, the content in the actual parameter will not be modified, and the efficiency is low, so it needs to be called by address.

	do
	{
		menu();
		printf("Please select:>");
		scanf("%d", &input);
		switch (input)
		{
			case ADD:
				//Add contact information
				AddContact(&con);//It will be troublesome to pass the parameters of the array and the number of array elements. Define them as a new structure
				break;
			case DEL:
				//Delete contact information
				DelContact(&con);
				break;
				//Find contact information
			case SEARCH:
				SearchContact(&con);
				break;
				//Modify contact information
			case MODIFY:
				ModifyContact(&con); 
				break;
				//Sort contact information
			case SORT:
				SortContact(&con);
				break;
				//Display information for all contacts
			case PRINT:
				//Although it is only printing information and will not change the information of the actual parameters, it is better to use address calling when considering the efficiency. It is better to use address calling for structure parameters.
				PrintContact(&con);
				break;
				//Clear all contact information
			case CLEAR:
				ClearContact(&con);
				break;
			case EXIT:
				//Now the memory space for storing contact information is opened dynamically. When exiting, the space should be released

				//Destroy address book
				DestoryContact(&con);
				printf("Exit address book\n");
				break;
			default:
				printf("Selection error, please re select:>");
				break;
		}
	} while (input);
	//If there is a member with the same name, the member with the first name will be operated. Because the traversal is from front to back, the case of the same name is not considered here.
	return 0;
}

3.2 # menu function:

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

Note here that the numbers of various functions correspond to the selection of case in switch.

3.3. Declaration part of enumeration type:

enum Option//Enumeration member variables start from 0 and increase by 1 in turn;
{
	//Variables in enumeration are generally capitalized.
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT,
	CLEAR
};

For the definition of enumeration type, it should be noted that the enumeration member variable starts from 0 by default and increases by 1 in sequence. You can also set the initial value

3.4 initialization of address book:

//Initialize address book function
void InitContact(Contact* pc)
{
	pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		//Failed to open up memory space
		perror("InitContact"); //Due to the operation in the function InitContact, if the development fails, the error is that the function has enough space
		return;  //Since the return type of InitContact function is void, you can directly return return.
	}
	//Here, the contents in the memory space pointed to by the structure pointer variable data are not initialized, which can be initialized or not initialized;

	(pc->sz) = 0;//After initialization, it defaults to 0
	(pc->capacity) = DEFAULT_SZ;//Default after initialization_ SZ
}

3.5. Add the contact information part of the address book:

    //Add contact information - Dynamic
void AddContact(Contact* pc)
{
	//Address book full - > capacity increase
	if (pc->sz == pc->capacity)
	{
		//increase capacity
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ)*sizeof(PeoInfo));
		if (ptr == NULL)
		{
			//Capacity increase failed
			perror("AddContact");
			perror("Capacity increase contact\n");
			return;
		}
		else
		{
			//Successful capacity increase 
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("Successful capacity increase\n");
		}
	}
	//If the address book is not full, you can add a new member and add a person's information
	printf("Please enter your first name:>");
	scanf("%s", pc->data[pc->sz].name);//
	printf("Please enter age:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("Please enter gender:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("Please enter the address:>");
	scanf("%s", pc->data[pc->sz].addr);
	printf("Please enter the phone number:>");
	scanf("%s", pc->data[pc->sz].tele);
	(pc->sz)++;
	printf("Successfully added contact persons\n");
	//Here, although the priority of [] is higher than - >,, data and [] cannot be combined first, because in a calling function, only the pointer variable pc is accepted in the formal parameter part
	//In other words, if the latter two are combined, the system does not know what data is, so it is wrong to combine them. That is, although [] has a higher priority than - >, the latter two cannot be combined
	//There will be errors in combination. Therefore, even if [] has a high priority, let data and - > combine first, that is, operate PC - > data first, and find the pointer variable data in the structure member variable,
	//And because the pointer variable data points to the address of the starting position of the memory space dynamically opened on the heap by the malloc function, which is equivalent to the address of the first element of the array. It is not a special case here, so,
	//It is equivalent to finding the array name of the array, that is, PC - > data = = = array name, knowing the array name, and then accessing the elements in the array through the array subscript.

3.6 ― part displaying contact information:

//Display contact information
void PrintContact(const Contact* pc)
{
	//Print out everyone's information, that is, sz personal information.
	int i = 0;
	//Print title
	printf("%-10s\t%-5s\t%-5s\t%-12s\t%-50s\n", "name", "Age", "Gender", "Telephone", "address");// \t === tab
	//print data
	for (i = 0; i < (pc->sz); i++)
	{
		printf("%-10s\t%-5d\t%-5s\t%-12s\t%-50s\n", pc->data[i].name, 
													pc->data[i].age,
													pc->data[i].sex,
													pc->data[i].tele,
													pc->data[i].addr);
	}
	//First, combine PC - > and data to find the pointer variable data in the structure, and the pointer variable stores the address of the starting position of the memory space dynamically opened on the heap by malloc function, which is equivalent to the address of the first element of the array,
	//This is not a special case, so it is equivalent to finding the array name of the array, that is, PC - > data = = = array name, knowing the array name, accessing the elements in the array through the array subscript, and finding the element with the array subscript i
	//That is, find a variable, and then access the person's name by clicking. Because the name is an array, the whole array is found, and the whole array can be represented by the array name, that is: PC - > data [i] Name = = = name, no sizeof and &,
	//Represents the address of the first element of the array, and then prints it with% s. except that age is a variable, all others are arrays, which is the same as name.

3.7 delete the part of contact information:

 
//Because this function is only to meet the needs of deleting, searching and modifying functions, and the implementation of the functions corresponding to these three functions will be in this c file, so for this function
//You just need to be there It can be executed in the c file, and it is not allowed to be exposed to others. Therefore, by adding static in front, it is fixed that the function is only in the current location c work in the document.
//static modifies a function, which essentially changes the link attribute of the function.
static int Find_By_Name(const Contact* pc,char name[])//If the array form is accepted, the use of const will not be considered.
{
	int i = 0;
	for (i = 0; i < pc -> sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)//equal
	//The first parameter finds the whole array first, which can be represented by the array name. It is not a special case, that is, it represents the address of the first element of the array. The second parameter is not a special case, but also the address of the first element of the array.
		{
			return i;
		}
	}
	return -1;
}
//Delete contact information
void DelContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("The address book is empty and cannot be deleted\n");
		return;
	}
	//Delete someone's information
	printf("Please enter the name of the person to delete:>");
	scanf("%s", name);
	//1. Find people to delete
	//Whether deleting, searching or modifying, you need to use the function of searching, so you take this function out separately to encapsulate a function;
	int pos=Find_By_Name(pc,name);//First level pointer pass parameter and array name pass parameter
	//The person does not exist
	if (pos == -1)
	{
		printf("The person to delete does not exist\n");
		return;
	}
	//2. This person exists and needs to be deleted. After deleting the person in this position of the array, the person behind the array will move forward one position in turn.
	int i = 0;
	for (i = pos; i < (pc->sz - 1); i++)
	{
		pc->data[i] = pc->data[i + 1]; 
	}
	//pc->sz -= 1;
	pc->sz--;
	//If you want to delete the last one, you can't delete it, because if there are 10 elements and the last subscript is 9, the judgment condition is < 9, so you don't enter the loop, but
	//After the cycle, there is PC - > SZ --, the number of members is less than 1, and when the employee information is displayed, the last employee cannot be accessed. Even if it is not deleted, it cannot be accessed,
	//The final result is the same as deleting the last person.
	//Assuming MAX=3, deleting the last element does not essentially delete it from the array, but because sz minus 1, the last element is not accessed during printing, which looks the same as the deletion effect. Now, due to
	//It seems that it has been deleted, but it has not been deleted in essence. What will happen if new elements are added?
	//Because after deletion, the number of elements will be reduced by 1, from 3 to 2. When adding a new element, the content of the new element will be directly placed at the position with subscript 2. In this case, even the last element before it
	//If it is not deleted, it will be overwritten by new elements. After adding, add 1 to the number of elements, and then print out the information after adding members. It is right.
	printf("Contact person deleted successfully\n");
}

3.8 ― part of finding contact information:

//Find contact information
void SearchContact(const Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	//Find someone's information
	printf("Please enter the name of the person you want to find:>");
	scanf("%s", name);
	int pos = Find_By_Name(pc, name);
	//The person you are looking for does not exist
	if (pos == -1)
	{
		printf("The person you are looking for does not exist\n");
		return;
	}
	else
	{
		//2. The person exists, find out and print out the information of the member
		//Print title
		printf("%-10s\t%-5s\t%-5s\t%-12s\t%-50s\n", "name", "Age", "Gender", "Telephone", "address");// \t === tab
		//print data
		printf("%-10s\t%-5d\t%-5s\t%-12s\t%-50s\n", 
			pc->data[pos].name,
			pc->data[pos].age,
			pc->data[pos].sex,
			pc->data[pos].tele,
			pc->data[pos].addr);
	}
}

3.9. Modify the part of contact information:

//Modify the information of the specified contact
void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	//Modify someone's information
	printf("Please enter the name of the person to modify:>");
	scanf("%s", name);
	int pos = Find_By_Name(pc, name);
	//The person to modify does not exist
	if (pos == -1)
	{
		printf("The person to modify does not exist\n");
		return;
	}
	else
	{
		printf("Please enter the name of the person after modification:>");
		scanf("%s", pc->data[pos].name);
		printf("Please enter the age of the person after modification:>");
		scanf("%d", &(pc->data[pos].age));
		printf("Please enter the gender of the person after modification:>");
		scanf("%s", pc->data[pos].sex);
		printf("Please enter the address of the person after modification:>");
		scanf("%s", pc->data[pos].addr);
		printf("Please enter the telephone number of the modified person:>");
		scanf("%s", pc->data[pos].tele);
		printf("Contact person information modified successfully\n");
	}
}

3.10. Sort the part of contact information:

enum Option_qsort
{
	exit_qsort,
	name,
	age,
	sex,
	addr,
	tele
};
void menu_qsort()
{
	printf("*****************************\n");
	printf("***** 1,name   2,age  *****\n");
	printf("***** 3,sex    4,addr *****\n");
	printf("***** 5,tele   0,exit_sort*\n");
	printf("*****************************\n");
}


//Sort by name
int Conpare_ByName(const void*e1, const void* e2)
{
	return strcmp( ((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name );
}

//Sort by age
int Conpare_ByAge(const void*e1, const void* e2)
{
	return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age;
}

//Sort by gender
int Conpare_BySex(const void*e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->sex, ((PeoInfo*)e2)->sex);
}

//Sort by address
int Conpare_ByAddr(const void*e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->addr, ((PeoInfo*)e2)->addr);
}

//Sort by phone
int Conpare_ByTele(const void*e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->tele, ((PeoInfo*)e2)->tele);
}

void print(Contact* pc)
{
	int i = 0;
	printf("%-10s\t%-5s\t%-5s\t%-12s\t%-50s\n", "name", "Age", "Gender", "Telephone", "address");

	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s\t%-5d\t%-5s\t%-12s\t%-50s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}
//Sort contact information
void SortContact(Contact* pc)
{
	int input = 0;
	do{
		menu_qsort();
		printf("Please select the sorting method:>");
		scanf("%d", &input);
		switch (input)
		{
			//Sort by name
		case name:
			//When calculating the number of array elements here, do not use the size of the whole array to compare with the size of the first element of the array, because when we sort here, we only sort the added members. For example, if the number of added members is 3,
			//Sort these three elements. If the opened array has 1000 elements, but only 3 elements are added, if the size of the whole array is larger than the size of the first element of the array, the result is 1000, which means sorting 1000 elements
			//This is not correct. You should sort the three elements added. PC - > SZ, the whole represents that the number of elements is 3. There is no need to calculate any more. Therefore, use the following code.
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByName);
			print(pc);
			break;
			//Sort by age
		case age:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAge);
			print(pc);
			break;
			//Sort by gender
		case sex:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_BySex);
			print(pc);
			break;
			//Sort by address
		case addr:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAddr);
			print(pc);
			break;
			//Sort by phone
		case tele:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByTele);
			print(pc);
			break;
			//Exit sorting
		case exit_qsort:
			printf("Exit sorting\n");
			printf("\n");
			break;
			//Selection error
		default:
			printf("Wrong arrangement, please re select:>\n");
			break;
		}
	}while (input);
}

To know the usage rules of the library function qsort, the above code can sort multiple times and can sort according to different requirements. It should be noted that when sorting different types of content, the comparison methods of the two elements are different, and different codes should be written.

3.11. Clear the part of all contact information:

//Clear all contact information
void ClearContact(Contact* pc)
{
	(pc->sz) = 0;
	memset(pc->data, 0, sizeof(pc->data));
	printf("Empty successfully\n");
	printf("\n");
	//In this process, sz is set to 0. When printing again, it does not enter the traversal cycle, does not print data, and directly outputs the program.
}


Use the memset memory setting function and set the number of array elements to 0. It is worth noting that sz is set to 0 in this process. When printing again, it will not enter the traversal cycle and print the number

It is reported that the effect is the same as that of clearing all contacts

3.12 destroy the part of the address book:

//Destroy address book
void DestoryContact(Contact* pc)
{
	//release
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

4, The code is rendered as a file:

4.1 test.c source file

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"

//mail list
//Everyone's information includes: name, age, gender, telephone number, address
//Add person's information, delete person's information, modify designated person's information, find designated person's information, sort address book's information, clear all information, display contact information, destroy address book

//Dynamic growth version
//1. After the initial initialization, the address book can store the information of three people,
//2. When the space is full, add two more contact information
//3. If it is found that it is not enough, add the information of 2 contacts each time

enum Option//Enumeration member variables start from 0 and increase by 1 in turn;
{
	//Variables in enumeration are generally capitalized.
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT,
	CLEAR
};

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

int main()
{
	int input = 0;
	//When creating an address book, the structure type is defined in the header file, so the header file should be introduced,
	There are currently several elements in the address book:
	//int sz = 0;
	//Create address book
	Contact con; //con is the address book, which can also be initialized directly. However, in order to better reflect modularization, a function is encapsulated in the initialization address book.
	//If you want to initialize some of them to 0, you must use functions.

	//Initialize address book
	//Use malloc function to dynamically open up a continuous memory space on the heap, and put the address of the starting position of the space in the structure pointer variable data.
	//Initialize integer variable sz=0;
	//Initialize the integer variable capacity to the current maximum capacity
	InitContact(&con);//When initializing the address book, the content in the address book should be modified. If it is called by value, the content in the actual parameter will not be modified, and the efficiency is low, so it needs to be called by address.

	do
	{
		menu();
		printf("Please select:>");
		scanf("%d", &input);
		switch (input)
		{
			case ADD:
				//Add contact information
				AddContact(&con);//It will be troublesome to pass the parameters of the array and the number of array elements. Define them as a new structure
				break;
			case DEL:
				//Delete contact information
				DelContact(&con);
				break;
				//Find contact information
			case SEARCH:
				SearchContact(&con);
				break;
				//Modify contact information
			case MODIFY:
				ModifyContact(&con); 
				break;
				//Sort contact information
			case SORT:
				SortContact(&con);
				break;
				//Display information for all contacts
			case PRINT:
				//Although it is only printing information and will not change the information of the actual parameters, it is better to use address calling when considering the efficiency. It is better to use address calling for structure parameters.
				PrintContact(&con);
				break;
				//Clear all contact information
			case CLEAR:
				ClearContact(&con);
				break;
			case EXIT:
				//Now the memory space for storing contact information is opened dynamically. When exiting, the space should be released

				//Destroy address book
				DestoryContact(&con);
				printf("Exit address book\n");
				break;
			default:
				printf("Selection error, please re select:>");
				break;
		}
	} while (input);
	//If there is a member with the same name, the member with the first name will be operated. Because the traversal is from front to back, the case of the same name is not considered here.
	return 0;
}

4.2 contact.c source file

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"

//Initialize address book function
void InitContact(Contact* pc)
{
	pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		//Failed to open up memory space
		perror("InitContact"); //Due to the operation in the function InitContact, if the development fails, the error is that the function has enough space
		return;  //Since the return type of InitContact function is void, you can directly return return.
	}
	//Here, the contents in the memory space pointed to by the structure pointer variable data are not initialized, which can be initialized or not initialized;

	(pc->sz) = 0;//After initialization, it defaults to 0
	(pc->capacity) = DEFAULT_SZ;//Default after initialization_ SZ
}





//Add contact information - Dynamic
void AddContact(Contact* pc)
{
	//Address book full - > capacity increase
	if (pc->sz == pc->capacity)
	{
		//increase capacity
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ)*sizeof(PeoInfo));
		if (ptr == NULL)
		{
			//Capacity increase failed
			perror("AddContact");
			perror("Capacity increase contact\n");
			return;
		}
		else
		{
			//Successful capacity increase 
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("Successful capacity increase\n");
		}
	}
	//If the address book is not full, you can add a new member and add a person's information
	printf("Please enter your first name:>");
	scanf("%s", pc->data[pc->sz].name);//
	printf("Please enter age:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("Please enter gender:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("Please enter the address:>");
	scanf("%s", pc->data[pc->sz].addr);
	printf("Please enter the phone number:>");
	scanf("%s", pc->data[pc->sz].tele);
	(pc->sz)++;
	printf("Successfully added contact persons\n");
	//Here, although the priority of [] is higher than - >,, data and [] cannot be combined first, because in a calling function, only the pointer variable pc is accepted in the formal parameter part
	//In other words, if the latter two are combined, the system does not know what data is, so it is wrong to combine them. That is, although [] has a higher priority than - >, the latter two cannot be combined
	//There will be errors in combination. Therefore, even if [] has a high priority, let data and - > combine first, that is, operate PC - > data first, and find the pointer variable data in the structure member variable,
	//And because the pointer variable data points to the address of the starting position of the memory space dynamically opened on the heap by the malloc function, which is equivalent to the address of the first element of the array. It is not a special case here, so,
	//It is equivalent to finding the array name of the array, that is, PC - > data = = = array name, knowing the array name, and then accessing the elements in the array through the array subscript.
}



//Display contact information
void PrintContact(const Contact* pc)
{
	//Print out everyone's information, that is, sz personal information.
	int i = 0;
	//Print title
	printf("%-10s\t%-5s\t%-5s\t%-12s\t%-50s\n", "name", "Age", "Gender", "Telephone", "address");// \t === tab
	//print data
	for (i = 0; i < (pc->sz); i++)
	{
		printf("%-10s\t%-5d\t%-5s\t%-12s\t%-50s\n", pc->data[i].name, 
													pc->data[i].age,
													pc->data[i].sex,
													pc->data[i].tele,
													pc->data[i].addr);
	}
	//First, combine PC - > and data to find the pointer variable data in the structure, and the pointer variable stores the address of the starting position of the memory space dynamically opened on the heap by malloc function, which is equivalent to the address of the first element of the array,
	//This is not a special case, so it is equivalent to finding the array name of the array, that is, PC - > data = = = array name, knowing the array name, accessing the elements in the array through the array subscript, and finding the element with the array subscript i
	//That is, find a variable, and then access the person's name by clicking. Because the name is an array, the whole array is found, and the whole array can be represented by the array name, that is: PC - > data [i] Name = = = name, no sizeof and &,
	//Represents the address of the first element of the array, and then prints it with% s. except that age is a variable, all others are arrays, which is the same as name.
}


 
//Because this function is only to meet the needs of deleting, searching and modifying functions, and the implementation of the functions corresponding to these three functions will be in this c file, so for this function
//You just need to be there It can be executed in the c file, and it is not allowed to be exposed to others. Therefore, by adding static in front, it is fixed that the function is only in the current location c work in the document.
//static modifies a function, which essentially changes the link attribute of the function.
static int Find_By_Name(const Contact* pc,char name[])//If the array form is accepted, the use of const will not be considered.
{
	int i = 0;
	for (i = 0; i < pc -> sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)//equal
	//The first parameter finds the whole array first, which can be represented by the array name. It is not a special case, that is, it represents the address of the first element of the array. The second parameter is not a special case, but also the address of the first element of the array.
		{
			return i;
		}
	}
	return -1;
}
//Delete contact information
void DelContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("The address book is empty and cannot be deleted\n");
		return;
	}
	//Delete someone's information
	printf("Please enter the name of the person to delete:>");
	scanf("%s", name);
	//1. Find people to delete
	//Whether deleting, searching or modifying, you need to use the function of searching, so you take this function out separately to encapsulate a function;
	int pos=Find_By_Name(pc,name);//First level pointer pass parameter and array name pass parameter
	//The person does not exist
	if (pos == -1)
	{
		printf("The person to delete does not exist\n");
		return;
	}
	//2. This person exists and needs to be deleted. After deleting the person in this position of the array, the person behind the array will move forward one position in turn.
	int i = 0;
	for (i = pos; i < (pc->sz - 1); i++)
	{
		pc->data[i] = pc->data[i + 1]; 
	}
	//pc->sz -= 1;
	pc->sz--;
	//If you want to delete the last one, you can't delete it, because if there are 10 elements and the last subscript is 9, the judgment condition is < 9, so you don't enter the loop, but
	//After the cycle, there is PC - > SZ --, the number of members is less than 1, and when the employee information is displayed, the last employee cannot be accessed. Even if it is not deleted, it cannot be accessed,
	//The final result is the same as deleting the last person.
	//Assuming MAX=3, deleting the last element does not essentially delete it from the array, but because sz minus 1, the last element is not accessed during printing, which looks the same as the deletion effect. Now, due to
	//It seems that it has been deleted, but it has not been deleted in essence. What will happen if new elements are added?
	//Because after deletion, the number of elements will be reduced by 1, from 3 to 2. When adding a new element, the content of the new element will be directly placed at the position with subscript 2. In this case, even the last element before it
	//If it is not deleted, it will be overwritten by new elements. After adding, add 1 to the number of elements, and then print out the information after adding members. It is right.
	printf("Contact person deleted successfully\n");
}

//Find contact information
void SearchContact(const Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	//Find someone's information
	printf("Please enter the name of the person you want to find:>");
	scanf("%s", name);
	int pos = Find_By_Name(pc, name);
	//The person you are looking for does not exist
	if (pos == -1)
	{
		printf("The person you are looking for does not exist\n");
		return;
	}
	else
	{
		//2. The person exists, find out and print out the information of the member
		//Print title
		printf("%-10s\t%-5s\t%-5s\t%-12s\t%-50s\n", "name", "Age", "Gender", "Telephone", "address");// \t === tab
		//print data
		printf("%-10s\t%-5d\t%-5s\t%-12s\t%-50s\n", 
			pc->data[pos].name,
			pc->data[pos].age,
			pc->data[pos].sex,
			pc->data[pos].tele,
			pc->data[pos].addr);
	}
}

//Modify the information of the specified contact
void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	//Modify someone's information
	printf("Please enter the name of the person to modify:>");
	scanf("%s", name);
	int pos = Find_By_Name(pc, name);
	//The person to modify does not exist
	if (pos == -1)
	{
		printf("The person to modify does not exist\n");
		return;
	}
	else
	{
		printf("Please enter the name of the person after modification:>");
		scanf("%s", pc->data[pos].name);
		printf("Please enter the age of the person after modification:>");
		scanf("%d", &(pc->data[pos].age));
		printf("Please enter the gender of the person after modification:>");
		scanf("%s", pc->data[pos].sex);
		printf("Please enter the address of the person after modification:>");
		scanf("%s", pc->data[pos].addr);
		printf("Please enter the telephone number of the modified person:>");
		scanf("%s", pc->data[pos].tele);
		printf("Contact person information modified successfully\n");
	}
}


enum Option_qsort
{
	exit_qsort,
	name,
	age,
	sex,
	addr,
	tele
};
void menu_qsort()
{
	printf("*****************************\n");
	printf("***** 1,name   2,age  *****\n");
	printf("***** 3,sex    4,addr *****\n");
	printf("***** 5,tele   0,exit_sort*\n");
	printf("*****************************\n");
}


//Sort by name
int Conpare_ByName(const void*e1, const void* e2)
{
	return strcmp( ((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name );
}

//Sort by age
int Conpare_ByAge(const void*e1, const void* e2)
{
	return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age;
}

//Sort by gender
int Conpare_BySex(const void*e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->sex, ((PeoInfo*)e2)->sex);
}

//Sort by address
int Conpare_ByAddr(const void*e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->addr, ((PeoInfo*)e2)->addr);
}

//Sort by phone
int Conpare_ByTele(const void*e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->tele, ((PeoInfo*)e2)->tele);
}

void print(Contact* pc)
{
	int i = 0;
	printf("%-10s\t%-5s\t%-5s\t%-12s\t%-50s\n", "name", "Age", "Gender", "Telephone", "address");

	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s\t%-5d\t%-5s\t%-12s\t%-50s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}
//Sort contact information
void SortContact(Contact* pc)
{
	int input = 0;
	do{
		menu_qsort();
		printf("Please select the sorting method:>");
		scanf("%d", &input);
		switch (input)
		{
			//Sort by name
		case name:
			//When calculating the number of array elements here, do not use the size of the whole array to compare with the size of the first element of the array, because when we sort here, we only sort the added members. For example, if the number of added members is 3,
			//Sort these three elements. If the opened array has 1000 elements, but only 3 elements are added, if the size of the whole array is larger than the size of the first element of the array, the result is 1000, which means sorting 1000 elements
			//This is not correct. You should sort the three elements added. PC - > SZ, the whole represents that the number of elements is 3. There is no need to calculate any more. Therefore, use the following code.
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByName);
			print(pc);
			break;
			//Sort by age
		case age:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAge);
			print(pc);
			break;
			//Sort by gender
		case sex:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_BySex);
			print(pc);
			break;
			//Sort by address
		case addr:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAddr);
			print(pc);
			break;
			//Sort by phone
		case tele:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByTele);
			print(pc);
			break;
			//Exit sorting
		case exit_qsort:
			printf("Exit sorting\n");
			printf("\n");
			break;
			//Selection error
		default:
			printf("Wrong arrangement, please re select:>\n");
			break;
		}
	}while (input);
}


//Clear all contact information
void ClearContact(Contact* pc)
{
	(pc->sz) = 0;
	memset(pc->data, 0, sizeof(pc->data));
	printf("Empty successfully\n");
	printf("\n");
	//In this process, sz is set to 0. When printing again, it does not enter the traversal cycle, does not print data, and directly outputs the program.
}



//Destroy address book
void DestoryContact(Contact* pc)
{
	//release
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

4.3 contact.h header file

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

//The definition of type and the address book should contain the information of 1000 people. Each person's information should include name, age, gender, telephone, address, etc., so it should be defined as a structure, which should be used in two source files, so it's best to define it in the header file, so it can be used frequently only by including the header file.

//Define structure type:
#define MAX_NAME 20 / / all uppercase
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30
#define MAX 1000



#define DEFAULT_SZ 3 / / the number of initialized contact information is 3
#define INC_SZ 2 / / increment is 2




typedef struct PeoInfo 
{
	//char name[20];
	//If you write it directly as a fixed value, it will die, which is not convenient for later modification. Therefore, use #define to define a constant, and then directly change the content in #define in the later stage.
	char name[MAX_NAME];
	//As above, gender is also defined by #define
	char sex[MAX_SEX];
	int age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;//Use typedef to rename the structure type to PeoInfo






//Structure nesting
//Contacts - dynamic
typedef struct Contact //rename
{
	//PeoInfo* data = (PeoInfo*)malloc(3 * sizeof(PeoInfo);// Store the information of the added contacts
	//However, it is still in a structure member variable. Generally, it is not initialized. Just write the content to the left of the equal sign.
	PeoInfo* data;//The structure pointer variable data points to the address of the starting position of the memory space dynamically opened on the heap to store contact information
	int sz;//Record the number of valid messages in the current address book
	int capacity;//Used to indicate the maximum capacity of the address book
}Contact;	
//Put the address of the first element of the memory space dynamically opened on the heap into the pointer variable data, and use the integer variable sz to record the number of existing effective contacts. Secondly, use the integer variable capacity to represent the maximum capacity of the current address book;
//Initially, the dynamic memory space can store the information of three people. Therefore, the initial value of capacity is the current maximum capacity






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

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

//Display contact information
void PrintContact(const Contact* pc);
//const is placed on the left of *, which means that the content pointed to by the pointer variable pc cannot be modified. pc points to the address book con, so the content in the address book, i.e. array and sz, cannot be changed, and because of the contact
//Each information of the array is a subset of each element in the array. Now it is required that the whole array cannot be changed, so the content of each element cannot be changed.

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

//Find contact information
void SearchContact(const Contact* pc);

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

//Sort contact information
void SortContact(Contact* pc);
//If const is added to the left of *, the content pointed to by pc cannot be changed. pc points to an array and sz. If sorting, the number of sz does not change, but there will be sorting among the elements of the array, which will lead to
//The contents of the array have changed, so const cannot be added.


//Clear all contact information
void ClearContact(Contact* pc);

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



The basic function of the dynamic memory allocation version of the address book has been realized. If it is helpful to you, remember to like the collection. Thank you~

Keywords: C Back-end

Added by Spiz on Thu, 27 Jan 2022 00:15:37 +0200