C Language Savior Extras [Address Book]

content

The static version implements the address book: (the size of the array cannot be modified)

The dynamic version implements the address book

We found that the statically developed address book list is fixed at 1000, which is less wasted space, and more needs to be re-modified. Can we use dynamic memory development to initialize the address book?

File version implements address book

After we exit the program, the address book is destroyed. Can we save the list we entered to a file for easy addition and viewing?

Complete Contact.h header file implementation declaration

Complete test.c source file implementation framework

Complete Contact.c source file implementation function


Why is the address book moving towards a data structure? There are two reasons:

1. After writing this blog, we are going to enter data structure learning

2. The address book is a summary of learning C language. It is recommended to write the address book by yourself, because implementing the C language with data structures requires a solid foundation. Writing the address book represents a good grasp of knowledge.

In order to standardize the code and write the code modularly, we use multi-file compilation

Implementation of the main function test.c
function declaration Contact.h
function implementation Contact.c

The static version implements the address book: (the size of the array cannot be modified)

1. Create an address book structure, which contains name, gender, phone number, age, and a record of the number of information that has been saved in the address book (to make it easy to modify the address book list when adding, deleting, checking, and modifying)

2. The header file should be included in the header file to prevent the header file from being included multiple times

3. When implementing the main function, the main function body should be constructed. In order to standardize the code, we can create an enumeration type and write the code through the enumeration type.

test.c body construction

enum contact
{
	EXIT,//0
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT,
};

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");
}

void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case EXIT:
			break;
		case ADD:
			break;
		case DEL:
		case SEARCH:
			break;
		case MODIFY:
			break;
		case SORT:
			break;
		case PRINT:
			break;
		}
	} while (input);
}


int main()
 {
	test();
	return 0;
}

4. For the implementation of the header file, we can put the enumeration just now into the header file, in which #define is used to facilitate modification. If we want to expand and shrink the address book list, such as the size of the name array, it is very convenient, just change the define Can

Contact.h body structure

//通讯录实现  接口申明
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#define MAX 1000
#define NAME 20
#define SEX 5
#define PHONE 12
#define ADDR 30
#define DEFAULF_SZ 3

typedef struct PeoInfo
{
	char name[NAME];//姓名
	char sex[SEX];//性别
	int age;//年龄
	char phone[PHONE];//电话
	char addr[ADDR];//地址
}PeoInfo;

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

静态版本
typedef struct Contact
{
	PeoInfo data[MAX];
	int sz;
}Contact;

 Declare the functions we need

// 初始化通讯录
void InitContact(Contact* pc);
//销毁通讯录
void  DestoryContact(Contact* pc);
//添加通讯录名单
void Addcontact(Contact * pc);
//打印通讯录名单
void PrintContact(const Contact* pc);
//删除通讯录名单
void DelContact(Contact* pc);
//查找通讯录名单
void SearchContact(const Contact* pc);
//改通讯录名单
void ModifyContact(Contact* pc);
//保存通讯录到文件
void SaveContact(const Contact* pc);

5. How to implement the functions required by the address book, we first need to initialize the address book after creating the address book (it will be initialized after it is created when the main function is called)

The Contact.c function implements the initialization of the address book, first initializing the contents of the array to 0

静态版本
void InitContact(Contact* pc)//初始化通讯录
{
	assert(pc);
	memset(pc->data,0,sizeof(pc->data));
	pc->sz = 0;
}

The Contact.c function implements adding the address book list. If the subscript of the array sz is full = 1000, stop putting it in

void Addcontact(Contact* pc)
{
	assert(pc);
	
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
		return;
	}
	printf("请输入姓名");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入年龄");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入手机号");
	scanf("%s", pc->data[pc->sz].phone);
	printf("请输入地址");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("添加成功!\n");
}

 The Contact.c function realizes finding the address book list, entering the name into the new array, traversing the search, and finding the sz subscript of the returned array

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

The Contact.c function implements deleting the address book list, entering the name into the new array, and traversing the search. Although the last element is not covered, it cannot be found there after sz--

void DelContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	//找到要删除的人
	printf("请输入要删除人的信息\n");
	char name[NAME] = {0};
	scanf("%s", name);
	int pos=FindContact(pc,name);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	int j = 0;
	for (j = pos; j < pc->sz-1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}

 Contact.c function to print the address book list

void SearchContact(const Contact* pc)
{
	char name[NAME] = { 0 };
	printf("请输入要查找人的名字");
	scanf("%s", name);
	int pos = FindContact(pc, name);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	printf("%-20s %-5s %-3s  %-12s %-30s\n", "姓名", "性别", "年龄", "手机号", "地址");
	printf("%-20s %-5s %-3d %-12s %-30s\n", pc->data[pos].name, pc->data[pos].sex, pc->data[pos].age, pc->data[pos].phone, pc->data[pos].addr);
}

 The Contact.c function implements modifying the address book list

void ModifyContact(Contact* pc)
{
	char name[NAME] = { 0 };
	printf("请输入要查找人的名字");
	scanf("%s", name);
	int pos = FindContact(pc, name);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		printf("请输入姓名");
		scanf("%s", pc->data[pc->sz].name);
		printf("请输入性别");
		scanf("%s", pc->data[pc->sz].sex);
		printf("请输入年龄");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("请输入手机号");
		scanf("%s", pc->data[pc->sz].phone);
		printf("请输入地址");
		scanf("%s", pc->data[pc->sz].addr);
		printf("修改成功!");
	}
}


The dynamic version implements the address book

We found that the statically developed address book list is fixed at 1000, which is less wasted space, and more needs to be re-modified. Can we use dynamic memory development to initialize the address book?

//动态版本
void InitContact(Contact* pc)
{
	assert(pc);
	//memset(pc->data,0,sizeof(pc->data));
	pc->sz = 0;
	pc->capacity = DEFAULF_SZ;
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact:malloc");
		return;      
	}
	memset(pc->data,0, pc->capacity * sizeof(PeoInfo));
}
 
增容通讯录
void CheckCapacity(Contact* pc)
{
	if (pc->capacity == pc->sz)
	{
		//增容
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));//realloc调整后的总大小
		if (tmp != NULL)
		{
			pc->data = tmp;
		}
		else
		{
			perror("CheckCapacity::realloc");
			return;
		}
		pc->capacity += 2;
		printf("增容成功\n");
	}
}

Since we have initialized the address book by using dynamic memory development, we need to check whether the address book is full when adding the address book list, and increase the capacity when it is full.


File version implements address book

After we exit the program, the address book is destroyed. Can we save the list we entered to a file for easy addition and viewing?

 

After the file is opened, the address book needs to be destroyed, and the address book written in the program is saved to the file

void  DestoryContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	printf("销毁成功\n");
}

void SaveContact(const Contact* pc)
{
	FILE* pf =fopen("Contact.txt", "wb");//二进制方式写进去
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return ;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);

	}
	printf("保存成功!\n");

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

 Initialize address book -- file version

Import and load the address book list we saved at the end into the program (at initialization)

//初始化通讯录 --文件版本
void LoadContact(Contact* pc)
{
	//打开文件
	FILE*pf =fopen("Contact.txt", "rb");
	if (pf == NULL)
	{
		perror("LoadContact::fopen");
		return;
	}
	//读文件
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))//返回的数值比要求读写的count数据小,代表读写完成,如果返回0代表没读取到
	{
		//通讯录初始化也要扩容,防止数据大于初始值
		CheckCapacity(pc);
		pc->data[pc -> sz] = tmp;//读取一个信息放到sz中,因为默认sz=0
		pc->sz++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULF_SZ;
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact:malloc");
		return;
	}
	memset(pc->data, 0, pc->capacity * sizeof(PeoInfo));

	//加载文件信息到通讯录中
	LoadContact(pc);

}

Complete Contact.h header file implementation declaration

//通讯录实现  接口申明
#define _CRT_SECURE_NO_WARNINGS 1

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

#define MAX 10
#define NAME 20
#define SEX 5
#define PHONE 12
#define ADDR 30
#define DEFAULF_SZ 3

typedef struct PeoInfo
{
	char name[NAME];
	char sex[SEX];
	int age;
	char phone[PHONE];
	char addr[ADDR];
}PeoInfo;

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

//静态版本
//typedef struct Contact
//{
//	PeoInfo data[MAX];
//	int sz;
//}Contact;

//动态版本
typedef struct Contact
{
	PeoInfo *data;//可以存放动态人数
	int sz;//记录通讯录中已经保存的信息个数
	int capacity;//记录通讯录当前的最大容量
}Contact;



// 初始化通讯录
void InitContact(Contact* pc);
//销毁通讯录
void  DestoryContact(Contact* pc);
//添加通讯录名单
void Addcontact(Contact * pc);
//打印通讯录名单
void PrintContact(const Contact* pc);
//删除通讯录名单
void DelContact(Contact* pc);
//查找通讯录名单
void SearchContact(const Contact* pc);
//改通讯录名单
void ModifyContact(Contact* pc);
//保存通讯录到文件
void SaveContact(const Contact* pc);

Complete test.c source file implementation framework

//专门测试通讯录功能

#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");
}

void test()
{
	Contact con;//创建通讯录

	InitContact(&con);//初始化通讯录


	int input = 0;
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case EXIT:
			SaveContact(&con);
			DestoryContact(&con);
			break;
		case ADD:
			Addcontact(&con);
			break;
		case DEL:
			DelContact(&con);
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SORT:
			break;
		case PRINT:
			PrintContact(&con);
			break;
		}
	} while (input);
}


int main()
 {
	test();
	return 0;
}

Complete Contact.c source file implementation function

//通讯录实现  接口(函数)实现
#include "contact.h"

//静态版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	memset(pc->data,0,sizeof(pc->data));
//	pc->sz = 0;
//}

//动态版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	//memset(pc->data,0,sizeof(pc->data));
//	pc->sz = 0;
//	pc->capacity = DEFAULF_SZ;
//	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
//	if (pc->data == NULL)
//	{
//		perror("InitContact:malloc");
//		return;      
//	}
//	memset(pc->data,0, pc->capacity * sizeof(PeoInfo));
//}
// 
//增容通讯录
void CheckCapacity(Contact* pc)
{
	if (pc->capacity == pc->sz)
	{
		//增容
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));//realloc调整后的总大小
		if (tmp != NULL)
		{
			pc->data = tmp;
		}
		else
		{
			perror("CheckCapacity::realloc");
			return;
		}
		pc->capacity += 2;
		printf("增容成功\n");
	}
}
//初始化通讯录 --文件版本
void LoadContact(Contact* pc)
{
	//打开文件
	FILE*pf =fopen("Contact.txt", "rb");
	if (pf == NULL)
	{
		perror("LoadContact::fopen");
		return;
	}
	//读文件
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))//返回的数值比要求读写的count数据小,代表读写完成,如果返回0代表没读取到
	{
		//通讯录初始化也要扩容,防止数据大于初始值
		CheckCapacity(pc);
		pc->data[pc -> sz] = tmp;//读取一个信息放到sz中,因为默认sz=0
		pc->sz++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULF_SZ;
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact:malloc");
		return;
	}
	memset(pc->data, 0, pc->capacity * sizeof(PeoInfo));

	//加载文件信息到通讯录中
	LoadContact(pc);

}

void Addcontact(Contact* pc)
{
	assert(pc);
	//静态版本
	/*if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
		return;
	}*/

	//动态版本
	CheckCapacity(pc);

	//录入信息
	printf("请输入姓名");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入年龄");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入手机号");
	scanf("%s", pc->data[pc->sz].phone);
	printf("请输入地址");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("添加成功!\n");
}
void PrintContact(const Contact* pc)
{
	assert(pc);	
	int i = 0;
	printf("%-20s %-5s %-3s %-12s %-30s\n", "姓名", "性别", "年龄", "手机号", "地址");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s %-5s %-3d %-12s %-30s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].phone, pc->data[i].addr);
	}
}

int FindContact(const Contact* pc,char name[])
{
	assert(pc);
	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)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	//找到要删除的人
	printf("请输入要删除人的信息\n");
	char name[NAME] = {0};
	scanf("%s", name);
	int pos=FindContact(pc,name);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	int j = 0;
	for (j = pos; j < pc->sz-1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}


void SearchContact(const Contact* pc)
{
	char name[NAME] = { 0 };
	printf("请输入要查找人的名字");
	scanf("%s", name);
	int pos = FindContact(pc, name);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	printf("%-20s %-5s %-3s  %-12s %-30s\n", "姓名", "性别", "年龄", "手机号", "地址");
	printf("%-20s %-5s %-3d %-12s %-30s\n", pc->data[pos].name, pc->data[pos].sex, pc->data[pos].age, pc->data[pos].phone, pc->data[pos].addr);
}


void ModifyContact(Contact* pc)
{
	char name[NAME] = { 0 };
	printf("请输入要查找人的名字");
	scanf("%s", name);
	int pos = FindContact(pc, name);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		printf("请输入姓名");
		scanf("%s", pc->data[pc->sz].name);
		printf("请输入性别");
		scanf("%s", pc->data[pc->sz].sex);
		printf("请输入年龄");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("请输入手机号");
		scanf("%s", pc->data[pc->sz].phone);
		printf("请输入地址");
		scanf("%s", pc->data[pc->sz].addr);
		printf("修改成功!");
	}
}

void  DestoryContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	printf("销毁成功\n");
}

void SaveContact(const Contact* pc)
{
	FILE* pf =fopen("Contact.txt", "wb");//二进制方式写进去
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return ;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);

	}
	printf("保存成功!\n");

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

Guess you like

Origin blog.csdn.net/weixin_63543274/article/details/124225658