C language project practice-address book (three versions of joint decomposition)

Project Description

Telephone numbers are indispensable in modern communication, but there are too many friends or people to contact, so you need to write down the phone numbers. However, the records on the books and the queries are too troublesome, so we can use computer programming to achieve a multi-functional and comprehensive The address book helps us deal with these phone numbers more conveniently.

The target function covers:

  1. Add contact information
  2. Delete specified contact information
  3. Find specific contact information
  4. Show all contact information
  5. Clear all contacts
  6. Sort all contacts by name
  7. Save contacts to file (file version)
  8. Load contacts from file (file version)

There are three versions to complete:

  1. Structure version (base version)
  2. Dynamic memory version
  3. File operation version

Project idea

flow chart

The main function is encapsulated in a corresponding function
Insert picture description here
Insert picture description here

Knowledge points used in the project

  1. Use of structure
  2. Use of dynamic memory malloc realloc calloc free
  3. File operation

Project function realization

Function declaration and abstract target

1. Abstract personal information

typedef struct PersonInfo 
{
    
     
char name[MAX_NAME]; 
char sex[SEX_NAME]; 
short age; 
char tele[TEL_NAME]; 
char addr[TEL_NAME]; 
}PersonInfo;

2. Abstract Address Book

typedef struct Contact {
    
     
//PersonInfo per[MAX_PER_NUM] ;静态版本 
int usedsize;//有效数据个数 动态版本 
PersonInfo* per; //动态版本
int capacity;//初始容量 
}Contact;//通讯录

Need to implement functions:

#ifndef __CONTACT_H__ 
#define __CONTACT_H__ 
#include<string.h> 
#include<stdio.h> 
#include<assert.h> 
#include<stdlib.h> 
enum Option 
{
    
     
EXIT, 
ADD, 
DEL, 
SEARCH, 
MONDIFY, 
SHOW, 
EMPTY, 
SORT 
};
#define MAX_NAME 20 
#define SEX_NAME 5 
#define TEL_NAME 12 
#define ADDR_NAME 20 //通讯录最多为1000人 
#define MAX_PER_NUM 1000 //动态扩容版本 
#define DEFAULT_SIZE 2; 
typedef struct PersonInfo 
{
    
     
char name[MAX_NAME]; 
char sex[SEX_NAME]; 
short age;
char tele[TEL_NAME]; 
char addr[TEL_NAME]; 
}PersonInfo; 
typedef struct Contact 
{
    
     
//PersonInfo per[MAX_PER_NUM] ;普通版本 
PersonInfo* per; 
int usedsize;//有效数据个数 
int capacity;//初始容量 
}Contact;//通讯录 
//初始化通讯录 
void InitContact(Contact *con); 
//添加成员 
void AddContact(Contact *con); 
//打印通讯录 
void ShowContact(Contact *con); 
//删除成员 
void DelContact(Contact *con); 
//查找成员 
int SearchContact(Contact *con); 
//清空通讯录 
void EmptyContact(Contact *con); 
//摧毁通讯录(动态版本) 
void DestoryContact(Contact *con); 
//文件版本 //保存联系人到文件 
void SaveContact(Contact *con); 
//加载联系人 
void LoadContact(Contact *con); 
#endif //__CONTACT_H__

The architecture and construction of the main function

#include"contact.h"


void menu() {
    
    
	printf("******************通讯录********************\n");
	printf("*** 1.add   2.show    3.delete 4.search ****\n");
	printf("*** 5.empty 6.distory 7.save   8.load   ****\n");
	printf("***************** 0.quit *******************\n");
	printf("********************************************\n");
}

int main()
{
    
    
	int select = 0;
	Contact contact;
	InitContact(&contact);
	do{
    
    
		menu();
		printf("Pleas intput you changce:");
		scanf("%d", &select);

		switch (select)
		{
    
    
		case QUIT: 
			printf("Good bye!\n");
			break;
		case ADD:
			AddContact(&contact);
			break;
		case SHOW:
			ShowContact(&contact);
			break;
		case DEL:
			DelContact(&contact);
			break;
		case SEARCH:
			SearchContact(&contact);
			break;
		case EMPTY:
			EmptyContact(&contact);
			break;
		case DESTORY:
			DestoryContact(&contact);
			break;
		case SAVE:
			SaveContact(&contact);
			break;
		case LOAD:
			LoadContact(&contact);
			break;
		default:
			break;
		}
	} while (select);
	system("pause");
	return 0;
}

Initialize the address book

void InitContact(Contact *pcon) {
    
    
	//普通版本
	//pcon->usedSize = 0; 
	//memset(pcon->per,0,sizeof(pcon->per));

	pcon->usedsize = 0;
	pcon->capacity = DEFAULT_SIZE;
	pcon->per = (PersonInfo *)malloc(
		sizeof(PersonInfo) * pcon->capacity);
	assert(pcon->per != NULL);

	LoadContact(pcon);//有可能文件中也有存储的联系人
}

Load contacts

void LoadContact(Contact *pcon) {
    
    
	FILE *pf = fopen("Contact.bat", "rb");
	PersonInfo tmp = {
    
     0 };
	if (pf == NULL)
	{
    
    
		return;
	}
	//fread函数的返回值是:读取成功的字节数
	while (fread(&tmp, sizeof(PersonInfo), 1, pf) > 0)
	{
    
    
		//必须判断是否为满,如果满了扩容
		CheckFullAndRe(pcon);
		pcon->per[pcon->usedsize++] = tmp;
	}
	fclose(pf);
	pf = NULL;
}

Add member

void AddContact(Contact *pcon) {
    
    
	//普通版本,无扩容解决办法
	//if(pcon->usedSize == MAX_NUMBER)
	//{
    
    
	//	printf("this contact is full\n");
	//	return;
	//}

	if (CheckFullAndRe(pcon) != 1)
	{
    
    
		printf("扩容失败\n");
		return;
	}

	printf("请输入姓名:");
	scanf("%s", pcon->per[pcon->usedsize].name);
	printf("请输入年龄:");
	scanf("%d", &(pcon->per[pcon->usedsize].age));
	printf("请输入性别:");
	scanf("%s", pcon->per[pcon->usedsize].sex);
	printf("请输入电话:");
	scanf("%s", pcon->per[pcon->usedsize].tele);
	printf("请输入住址:");
	scanf("%s", pcon->per[pcon->usedsize].addr);
	pcon->usedsize++;
	printf("添加成功\n");
}

Print address book

void ShowContact(Contact *pcon) {
    
    
	int i = 0;
	printf("%-10s %-5s %-5s %-11s %-20s\n", "姓名", "年龄",
		"性别", "电话", "住址");
	for (i = 0; i < pcon->usedsize; i++)
	{
    
    
		printf("%-10s %-5d %-5s %-11s %-20s\n",
			pcon->per[i].name, pcon->per[i].age,
			pcon->per[i].sex, pcon->per[i].tele,
			pcon->per[i].addr);
	}
}

Delete member

void DelContact(Contact *pcon) {
    
    
	int index = SearchContact(pcon);
	int i = 0;
	if (index == -1)
	{
    
    
		printf("删除失败,查无此人\n");
		return;
	}
	for (i = index; i < pcon->usedsize - 1; i++)
	{
    
    
		pcon->per[i] = pcon->per[i + 1];
	}
	pcon->usedsize--;
	printf("删除成功\n");
}

Find members

int SearchContact(Contact *pcon) {
    
    
	int i = 0;
	char name[MAX_NAME] = {
    
     0 };
	if (pcon->usedsize == 0)
	{
    
    
		printf("通讯录为空\n");
		return -1;
	}
	printf("请输入你要删除的姓名:");
	scanf("%s", name);
	for (i = 0; i < pcon->usedsize; i++)
	{
    
    
		if (strcmp(pcon->per[i].name, name) == 0)
		{
    
    
			return i;
		}
	}
	return -1;
}

Empty address book

void EmptyContact(Contact *pcon) {
    
    
	pcon->usedsize = 0;
}

Destroy the address book (dynamic version)

void DestoryContact(Contact *pcon) {
    
    
	SaveContact(pcon);
	free(pcon->per);
	pcon->per = NULL;//预防野指针  
	pcon->capacity = 0;
	pcon->usedsize = 0;
}

Save contacts to file (file version)

void SaveContact(Contact *pcon) {
    
    
	int i = 0;
	FILE *pf = fopen("Contact.bat", "wb");
	assert(pf != NULL);
	for (i = 0; i < pcon->usedsize; i++)
	{
    
    
		fwrite(pcon->per + i, sizeof(PersonInfo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

Problems encountered

Regardless of whether the address book is a static version or a dynamic version, the number of people stored has a limit.

Although dynamic memory can be opened up as much as needed, it still needs to be defined in programming.

Solution

Design an extension function, if the storage is insufficient, open up more memory.

Expanding address book

static int CheckFullAndRe(Contact *pcon) {
    
    
	if (pcon->usedsize == pcon->capacity)
	{
    
    
		PersonInfo * ptr = NULL;
		ptr = (PersonInfo *)realloc(pcon->per,
			sizeof(PersonInfo) * pcon->capacity * 2);
		if (ptr != NULL)
		{
    
    
			pcon->per = ptr;
			pcon->capacity *= 2;
			printf("扩容成功\n");
			return 1;
		}
		else
		{
    
    
			return 0;//扩容失败
		}
	}

	return 1;
}

Project source code

Source code of my address book project: https://github.com/GagaAutom/C-programming-language/blob/master/my_contact/contact

Guess you like

Origin blog.csdn.net/qq_40893595/article/details/105547369