系列文章目录

第一章 【数据结构C++】线性表/顺序表-数组与vector
第二章 【数据结构C++】线性表/顺序表-数据类型、增删改查操作
第三章 【数据结构C++】线性表/顺序表-实战:通信录



前言

这篇blog面向刚入门学习数据结构的小伙伴们,参考第二章的函数模板可以实现这个通信录的项目。按照下面步骤,不需任何修改就可以顺利编译。

一、visual studio2022准备工作

【数据结构C++】线性表/顺序表-实战:通信录-LMLPHP

【数据结构C++】线性表/顺序表-实战:通信录-LMLPHP
【数据结构C++】线性表/顺序表-实战:通信录-LMLPHP
然后在项目中头文件添加xxx.h文件,在源文件添加xxx.c/xxx.cpp文件。
【数据结构C++】线性表/顺序表-实战:通信录-LMLPHP

二、具体代码实现

1.contacts.h文件

//条件编译
#ifndef __CONTACT_H__
#define __CONTACT_H__

//头文件列表
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#include <string.h>

//忽略警告
#pragma warning(disable:4996)

//宏
#define INITCAP 128//初始化长度
#define INCREMENT 32//自增长度
#define FILE_NAME "contact_back"

//声明:
//联系人结构体
typedef struct person {
	char name[32];//姓名 性别 年龄 电话 地址
	char sex[8];
	unsigned char age;
	char phone[16];
	char adds[64];
}person_t, * person_p, ** person_pp;

//通讯录结构体
typedef struct contact {
	int cap;//最大长度
	int size;//当前长度
	person_p contactList;//联系人列表
}contact_t, * contact_p, ** contact_pp;

//函数声明
void initContact(contact_pp c);//初始化通讯录
void addContact(contact_p c, person_p p);//添加联系人
void showContact(contact_p c);//打印联系人列表
void delContact(contact_p c, char* del_name);//删除
void emptyContact(contact_p c);//清空
void destroyContact(contact_p c);//摧毁通讯录
int  searchContact(contact_p c, char* search_name);//查找
void sortContact(contact_p c);//排序
void modContact(contact_p c);//修改
void helpContact();//帮助
void exitContact(contact_p c);//退出
int  isContactEmpty(contact_p c);//判空
int fileLoad(contact_p c);//下载到项目
int fileStore(contact_p c);//储存到文件


#endif __CONTACT_H__ 

2.contacts.c文件

/*
 *
 *  Created on: 2023.3.13
 *      Author: 宇宙修理员
 */


#include "contacts.h"

 //判空
 //空:1
 //不空:0
int isContactEmpty(contact_p c)
{
	assert(c);	//断言,假=0

	return c->size == 0 ? 1 : 0;
}

//初始化
void initContact(contact_pp c)
{
	assert(c);

	//申请通讯录空间
	*c = (contact_p)malloc(sizeof(contact_t));
	if (NULL == *c) {
		perror("malloc");
		exit(1);
	}

	//申请成员空间
	(*c)->contactList = (person_p)malloc(sizeof(person_t) * INITCAP);
	if (NULL == (*c)->contactList) {
		perror("malloc");
		exit(2);
	}

	//初始化长度和容量
	(*c)->cap = INITCAP;
	(*c)->size = 0;

	fileLoad(*c);
}

//从文件读取通讯录信息
int fileLoad(contact_p c)
{
	FILE* fp;
	person_t p;
	int i = 0;

	assert(c);

	//打开文件
	fp = fopen(FILE_NAME, "rb");
	if (NULL == fp) {
		perror("fopen");
		return -2;
	}

	while (1) {
		//读取到p
		fread(&p, sizeof(person_t), 1, fp);
		if (0 != feof(fp)) {
			break;
		}
		//将读取的添加到通讯录
		addContact(c, &p);
	}
	fclose(fp);

	return 0;
}


//判满
//满:1 
//未满:0
static int isContactFull(contact_p c)
{
	assert(c);

	return c->size >= c->cap ? 1 : 0;
}


//自增
static int incContact(contact_p c)
{
	person_p new_c = NULL;

	assert(c);

	//申请新空间
	new_c = (person_p)realloc(c->contactList, (c->cap + INCREMENT) * sizeof(person_t));
	if (NULL == new_c) {
		perror("realloc");
		return 0;
	}

	//将新空间分配给旧空间
	c->contactList = new_c;
	c->cap += INCREMENT;
	printf("Is full, increse success!\n");
	return 1;
}

//添加联系人
void addContact(contact_p c, person_p p)
{
	assert(c);
	assert(p);

	//如果不空直接添加,如果空就先自增再添加
	if (!isContactFull(c) || incContact(c)) {
		c->contactList[c->size] = *p;
		c->size++;
	}
}

//查找
//是空的:打印空
//没找到:返回 -1
//找到:返回下标
int searchContact(contact_p c, char* search_name)
{
	int i = 0;

	assert(c);
	assert(search_name);

	//通讯录是空的
	if (isContactEmpty(c)) {
		printf("Contact is empty!\n");
	}

	for (i = 0; i < c->size; i++) {
		if (0 == strcmp(c->contactList[i].name, search_name)) {
			break;
		}
	}

	//没找到
	if (i == c->size)
	{
		return -1;
	}

	//找到返回下标
	return i;


}


//按名字排序
void sortContact(contact_p c)
{
	int i = 0;
	int j = 0;
	int pos = 0;
	person_t temp;

	assert(c);

	//是空的就不用排
	if (isContactEmpty(c)) {
		printf("Contact is empty!\n");
		return;
	}

	//不空用冒泡法按名字排序
	for (i = c->size - 1; i > 0; i--) {
		for (j = 0; j < i; j++) {
			if (1 == strcmp(c->contactList[j].name, c->contactList[j + 1].name)) {
				temp = c->contactList[j];
				c->contactList[j] = c->contactList[j + 1];
				c->contactList[j + 1] = temp;
				pos = 1;
			}
		}
		if (0 == pos)
		{

			break;
		}
	}

	printf("Done...\n");
}

//修改联系人
void modContact(contact_p c)
{
	char name[32];
	int i = 0;
	char key_mod[8];

	assert(c);


	if (isContactEmpty(c)) {
		printf("Contact is empty!\n");
		return;
	}

	//输入要修改的人的名字
	printf("Please input the name whicth you want to modify:");
	scanf("%s", name);

	//查找要修改人的下标
	i = searchContact(c, name);
	if (-1 == i)
	{
		printf("Not find!\n");
		return;
	}

	//打印信息
	printf("------------------------------------------------------------------------------\n");
	printf("| name      | sex  | age | phone           | adds                            |\n");
	printf("| %-10s| %-5s| %-4d| %-16s| %-32s|\n", c->contactList[i].name, \
		c->contactList[i].sex, c->contactList[i].age, \
		c->contactList[i].phone, c->contactList[i].adds);
	printf("------------------------------------------------------------------------------\n");

	//输入要修改的关键字
	printf("Please input the infor whicth you want to modify:");
	fflush(stdin);
	scanf("%s", key_mod);

	//寻找要修改的关键字

	//如果要修改名字
	if (0 == strcmp("name", key_mod)) {
		printf("Please input new name:");
		fflush(stdin);//注意要清空输入缓冲区
		scanf("%s", c->contactList[i].name);
		printf("Done...\n");
		return;
	}

	//如果要修改性别
	if (0 == strcmp("sex", key_mod)) {
		printf("Please input new sex:");
		fflush(stdin);
		scanf("%s", c->contactList[i].sex);
		printf("Done...\n");
		return;
	}

	//如果要修改年龄
	if (0 == strcmp("age", key_mod)) {
		printf("Please input new age:");
		fflush(stdin);
		scanf("%d", &c->contactList[i].age);
		printf("Done...\n");
		return;
	}

	//如果要修改电话号码
	if (0 == strcmp("phone", key_mod)) {
		printf("Please input new phone:");
		fflush(stdin);
		scanf("%s", c->contactList[i].phone);
		printf("Done...\n");
		return;
	}

	//如果要修改地址
	if (0 == strcmp("adds", key_mod)) {
		printf("Please input new adds:");
		fflush(stdin);
		scanf("%s", c->contactList[i].adds);
		printf("Done...\n");
		return;
	}

	//没有找到要修改的关键字
	printf("ERROR!!\n");
}

//删除
void delContact(contact_p c, char* del_name)
{
	int i = 0;
	int j = 0;
	assert(c);

	i = searchContact(c, del_name);
	if (-1 == i)
	{
		printf("Not find!\n");
		return;
	}

	//将后面的成员前移
	for (j = i; j < c->size; j++) {
		c->contactList[j] = c->contactList[j + 1];
	}

	c->size--;
	printf("Done...\n");
}

//清空通讯录
void emptyContact(contact_p c)
{
	assert(c);

	//直接将当前大小置0
	c->size = 0;
	printf("Done...\n");
}

//打印信息
void showContact(contact_p c)
{
	int i = 0;

	assert(c);

	if (isContactEmpty(c)) {
		printf("Contact is empty!\n");
		return;
	}

	printf("\ntotal:%d\n", c->size);//打印总人数

	//打印详细信息
	printf("------------------------------- contacts -------------------------------------\n");
	printf("| name      | sex  | age | phone           | adds                            |\n");
	printf("------------------------------------------------------------------------------\n");
	for (; i < c->size; i++) {
		printf("| %-10s| %-5s| %-4d| %-16s| %-32s|\n", c->contactList[i].name, \
			c->contactList[i].sex, c->contactList[i].age, \
			c->contactList[i].phone, c->contactList[i].adds);
	}
	printf("------------------------------------------------------------------------------\n\n");
}

//帮助(使用手册)
void helpContact()
{
	printf("\n");
	printf("-----------------------------------  HELP  -----------------------------------\n");
	printf("| You could use this app store up some information about your friends.       |\n");
	printf("| 1、you can add information by choose ( 1 ).                                |\n");
	printf("| 2、you can delect someone by choose ( 2 ).                                 |\n");
	printf("| 3、you can search someone by choose ( 3 ).                                 |\n");
	printf("| 4、you can change some's information by choose ( 4 ).                      |\n");
	printf("| 5、you can show information list by choose ( 5 ).                          |\n");
	printf("| 6、you can empty all information by choose ( 6 ).                          |\n");
	printf("| 7、you can sort people by choose ( 7 ).                                    |\n");
	printf("------------------------------------------------------------------------------\n\n");
}



//储存到文件
int fileStore(contact_p c)
{
	FILE* fp;
	int i = 0;

	assert(c);

	//打开文件
	fp = fopen(FILE_NAME, "wb");
	if (NULL == fp) {
		perror("fopen");
		return -1;
	}

	//一次储存一个人大小的内容
	for (; i < c->size; i++) {
		fwrite(c->contactList + i, sizeof(person_t), 1, fp);
	}

	fclose(fp);

	return 0;
}

//摧毁通讯录
void destroyContact(contact_p c)
{
	assert(c);

	fileStore(c);
	free(c->contactList);//释放陈燕
	c->contactList = NULL;
	free(c);//释放整体
	c = NULL;
}

//退出
void exitContact(contact_p c)
{
	int n = 0;
	printf("\nAre you sure quit ?\n");
	while (1)
	{
		printf("----------------\n");
		printf("| 1.YES | 2.NO |\n");
		printf("----------------\n");

		scanf("%d", &n);
		if (1 == n)
		{
			destroyContact(c);
			exit(0);
		}
		else if (2 == n)
		{
			return;
		}
		else
		{
			printf("Error ! \n");
		}
	}

}

3.contactMain.c文件

/*
 *
 *  Created on: 2023.3.13
 *      Author: Chen Jingyan
 */


#include "contacts.h"

 //菜单
static void meun() {
	printf("\n");
	printf("Welcome...\n");
	printf("-----------------------------------  CONTACTS  --------------------------------\n");
	printf("--           1.Add                                2.Delect                   --\n");
	printf("--           3.Search                             4.Edit                     --\n");
	printf("--           5.Show                               6.Empty                    --\n");
	printf("--           7.Sort                               8.Help                     --\n");
	printf("--           0.Exit                                                          --\n");
	printf("-------------------------------------------------------------------------------\n");
	printf("\n");
}

//添加
static void myAdd(contact_p c) {
	person_t p;

	assert(c);

	printf("Please input information<name,sex,age,phone,addr>:\n");
	scanf("%s %s %d %s %s", p.name, p.sex, &p.age, p.phone, p.adds);
	addContact(c, &p);
}

//删除
static void myDel(contact_p c) {
	char del_name[32];
	int n = 0;
	assert(c);

	if (isContactEmpty(c)) {
		printf("Contact is empty!\n");
		return;
	}

	printf("Please input the name whicth you want delect:");
	scanf("%s", del_name);
	printf("\nAre you sure delect: %s ?\n", del_name);
	while (1)
	{
		printf("----------------\n");
		printf("| 1.YES | 2.NO |\n");
		printf("----------------\n");

		scanf("%d", &n);
		if (1 == n)
		{
			delContact(c, del_name);
			return;
		}
		else if (2 == n)
		{
			return;
		}
		else
		{
			printf("Error ! \n");
		}
	}

}

//查找
static void mySearch(contact_p c)
{
	char search_name[32];
	int pos = 0;
	int i = 0;

	assert(c);

	if (isContactEmpty(c)) {
		printf("Contact is empty!\n");
		return;
	}

	printf("Please input rhe name whicth you want to search:");
	scanf("%s", search_name);
	pos = searchContact(c, search_name);
	if (-1 == pos) {
		printf("Not find!\n");
	}
	else {

		printf("------------------------------------------------------------------------------\n");
		printf("| name      | sex  | age | phone           | adds                            |\n");
		printf("| %-10s| %-5s| %-4d| %-16s| %-32s|\n", c->contactList[i].name, \
			c->contactList[i].sex, c->contactList[i].age, \
			c->contactList[i].phone, c->contactList[i].adds);
		printf("------------------------------------------------------------------------------\n");
	}
}

int main()
{
	int s = -1;//选择控制变量
	contact_p myContact = NULL;//声明通讯录
	system("color 2");
	initContact(&myContact);//初始化
	while (1) {
		meun();
		printf("Please select<0~7>:");
		fflush(stdin);
		scanf("%d", &s);
		switch (s) {
		case 1:system("cls");
			myAdd(myContact);//添加联系人
			system("pause");
			break;
		case 2:system("cls");
			myDel(myContact);//删除联系人
			system("pause");
			break;
		case 3:system("cls");
			mySearch(myContact);//查找并打印联系人
			system("pause");
			break;
		case 4:system("cls");
			modContact(myContact);//修改联系人
			system("pause");
			break;
		case 5:system("cls");
			showContact(myContact);//显示联系人列表
			system("pause");
			break;
		case 6:system("cls");
			emptyContact(myContact);//清空通讯录
			system("pause");
			break;
		case 7:system("cls");
			sortContact(myContact);//排序通讯录
			system("pause");
			break;
		case 8:system("cls");
			helpContact();//帮助
			system("pause");
			break;
		case 0:system("cls");
			exitContact(myContact);//退出
			break;
		default:printf("ERROR SELECTION !!!\n");//错误选择
			system("pause");
			break;
		}
		system("cls");//清屏
	}

	return 0;
}


效果图:
【数据结构C++】线性表/顺序表-实战:通信录-LMLPHP
查询界面:
【数据结构C++】线性表/顺序表-实战:通信录-LMLPHP

03-13 17:03