顺序表实现简易通讯录 附带源码

目录

1.通讯录的功能

2.头文件与执行文件分离

3.通讯录的底层原理:

4.顺序表的实现

5.1 conta.h 的讲解

源码:

结构体讲解:

其余讲解:

5.2 contact.cpp 的讲解

源码:

5.2.1 InitContact() 初始化函数的讲解

5.2.2 LoadContact() 读取历史数据函数的讲解

5.2.3 AddContact() 添加联系人函数的讲解

5.2.4 FindContact() 查找联系人函数的讲解

5.2.5 DelContact() 删除联系人函数的讲解

5.2.6 ShowContact() 打印通讯录函数

5.2.7 ModifyContact() 修改联系人信息

5.2.8 DestroyContact() 销毁函数的讲解

5.2.8 SaveContact() 存储数据函数


动态顺序表的实现:

动态顺序表的实现icon-default.png?t=N7T8https://blog.csdn.net/2301_80122797/article/details/137592121
文件操作:
文件操作详解icon-default.png?t=N7T8https://blog.csdn.net/2301_80122797/article/details/137268867

1.通讯录的功能

(1).通讯录的初始化(读取历史数据)

(2).添加联系人

(3).删除联系人

(4).打印通讯录内容

(5).查找联系人

(6).修改联系人信息

(7).销毁通讯录

(8).读取数据

(9).存储数据

2.头文件与执行文件分离

通讯录相关文件:

conta.h

contact.cpp

链表相关文件 :

sqlist.h

List.cpp
存储通讯录数据文件:

contact.txt 

3.通讯录的底层原理:

        顺序表实现的通讯录底层原理主要涉及数据结构的选择和内存管理。主要是以顺序表来实现的。

4.顺序表的实现

有关动态顺序表的实现请看这篇博客

动态顺序表的实现icon-default.png?t=N7T8https://blog.csdn.net/2301_80122797/article/details/1375921215.基于动态顺序表实现通讯录

5.1 conta.h 的讲解

源码:

const  int NAME = 20;
const  int SEX =10;
const  int TEL =20;
const  int DRESS =20;

//姓名 性别 年龄 电话 地址
struct per
{
	char name[NAME];
	char gender[SEX];
	int age;
	char tel[TEL];
	char dress[DRESS];
};

typedef struct per permessage;

typedef struct List contact;

void InitContact(contact* con);
void AddContact(contact* con);
void DelContact(contact* con);
void ShowContact(contact* con);
int FindContact(contact* con,char *str);
void ModifyContact(contact* con);
void DestroyContact(contact* con);
void LoadContact(contact* con);//读取数据
void SaveContact(contact* con);//存储数据

 结构体讲解:

const  int NAME = 20;
const  int SEX =10;
const  int TEL =20;
const  int DRESS =20;

//姓名 性别 年龄 电话 地址
struct per
{
	char name[NAME];
	char gender[SEX];
	int age;
	char tel[TEL];
	char dress[DRESS];
};

 先定义一个结构体,用来存储个人信息,包含姓名,性别,年龄,电话,地址。

其余讲解:

typedef struct per permessage;

typedef struct List contact;

void InitContact(contact* con);
void AddContact(contact* con);
void DelContact(contact* con);
void ShowContact(contact* con);
int FindContact(contact* con,char *str);
void ModifyContact(contact* con);
void DestroyContact(contact* con);
void LoadContact(contact* con);//读取数据
void SaveContact(contact* con);//存储数据

我们把 struct per 重命名为 permessage 更方便来使用,这里重点讲一下前置声明 typedef struct List contact; 由于已经实现好了顺序表,所以在顺序表的基础上实现通讯录,就要给顺序表重新起个名字,这里再次对 struct List 重命名为 contact。所以contact也就是个顺序表了。

5.2 contact.cpp 的讲解

源码:

#include"sqlist.h"
#include"conta.h"


void LoadContact(contact* con) 
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}

	//循环读取文件数据
	permessage info;
	while (fread(&info, sizeof(permessage), 1, pf))
	{
		pushback(con, info);
	}
	printf("历史数据导入通讯录成功!\n");
}

void SaveContact(contact* con) {
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}
	//将通讯录数据写入文件
	for (int i = 0; i < con->size; i++)
	{
		fwrite(con->arr+i, sizeof(permessage), 1, pf);
	}
	printf("通讯录数据保存成功!\n");
}


void InitContact(contact* con)
{
	con->arr = NULL;
	con->cap = con->size = 0;
	LoadContact(con);
}
void AddContact(contact* con)
{
	permessage newnode;

	printf("input name\n");
	cin >> newnode.name;
	printf("input gender\n");
	cin >> newnode.gender;
	printf("input age\n");
	cin >> newnode.age;
	printf("input tel\n");
	cin >> newnode.tel;
	printf("input dress\n");
	cin >> newnode.dress;

	pushback(con, newnode);


}
void DelContact(contact* con)
{
	char nn[100];
	printf("input you ready delete name\n");
	cin >> nn;
	int findd = FindContact(con, nn);
	if (findd == -1)
	{
		cout << "no name ,please reinput" << endl;
	}
	else
	{
		erase(con, findd);
		cout << "delete scussfully" << endl;
	}
}
void ShowContact(contact* con)
{
	printf("name  gender  age    tel   dress\n");

	for (int i = 0; i < con->size; i++)
	{
		printf("%-6s %-6s %-6d %-6s %-6s\n", con->arr[i].name, con->arr[i].gender, con->arr[i].age, con->arr[i].tel, con->arr[i].dress);

	}
	return;

}

int FindContact(contact* con,char* nammm)
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr[i].name, nammm) == 0)
		{
			return i;
		}
	}
	return -1;
}
void ModifyContact(contact* con)
{
	char nemmm[100];
	printf("input name\n");
	cin >> nemmm;

	int findd = FindContact(con, nemmm);
	if (findd < 0)
	{
		printf("name if not\n");
		return;
	}
	printf("modity befor :%4s %4s %4d %4s %4s\n", con->arr[findd].name, con->arr[findd].gender, con->arr[findd].age, con->arr[findd].tel, con->arr[findd].dress);
	printf("input modity name age sex tel dress\n");
	scanf("%s%s%d%s%s", &con->arr[findd].name, &con->arr[findd].gender, &con->arr[findd].age, &con->arr[findd].tel, &con->arr[findd].dress);

	printf("modity voer :%4s %4s %4d %4s %4s\n", con->arr[findd].name, con->arr[findd].gender, con->arr[findd].age, con->arr[findd].tel, con->arr[findd].dress);

}
void DestroyContact(contact* con)
{
	SaveContact(con);
	destort(con);
}

5.2.1 InitContact() 初始化函数的讲解

声明:
void InitContact(contact* con);
定义:
void InitContact(contact* con)
{
	con->arr = NULL;
	con->cap = con->size = 0;
	LoadContact(con);
}

(1).把顺序表置为空,再把顺序表的容量和已存储元素的数量置为0。

(2).同时要读取历史数据。

5.2.2 LoadContact() 读取历史数据函数的讲解

有关文件操作的内容请看本篇博客:

fread()函数的讲解icon-default.png?t=N7T8https://blog.csdn.net/2301_80122797/article/details/137268867#:~:text=%7D-,5.2.4%20fread%C2%A0,-size_t%20fread%20(

声明:
void LoadContact(contact* con);
定义:
void LoadContact(contact* con) 
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}

	//循环读取文件数据
	permessage info;//创建一个通讯录结构体
	while (fread(&info, sizeof(permessage), 1, pf))
	{
		pushback(con, info);//读取后再尾插
	}
	printf("历史数据导入通讯录成功!\n");
}

(1).首先创建文件指针,以二进制形式读取文件。

(2).创建一个通讯录结构体,然后循环读取文件,直到遇到EOF停下,每读取一次,添加到顺序表后面。这样顺序表中的每个元素就是一个结构体。


 

5.2.3 AddContact() 添加联系人函数的讲解

pushback函数的讲解icon-default.png?t=N7T8https://blog.csdn.net/2301_80122797/article/details/137592121#:~:text=%E5%B0%86size%2B%2B%E3%80%82-,3.2.4%C2%A0pushback()%E5%B0%BE%E6%8F%92,-%E5%A3%B0%E6%98%8E%EF%BC%9A

声明:
void AddContact(contact* con);
定义:
void AddContact(contact* con)
{
	permessage newnode;

	printf("input name\n");
	cin >> newnode.name;
	printf("input gender\n");
	cin >> newnode.gender;
	printf("input age\n");
	cin >> newnode.age;
	printf("input tel\n");
	cin >> newnode.tel;
	printf("input dress\n");
	cin >> newnode.dress;

	pushback(con, newnode);


}

(1).首先创建一个通讯录结构体然后依次对结构体输入 姓名 性别 年龄 电话 地址。

(2).输入完成后,由于通讯录底层是顺序表,所以我们直接调用尾插函数,将这个新创建的结构体添加到顺序表中。

5.2.4 FindContact() 查找联系人函数的讲解

声明:
int FindContact(contact* con,char *str);

(我们这里以联系人姓名来查找)

定义:
int FindContact(contact* con,char* nammm)
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr[i].name, nammm) == 0)
		{
			return i;
		}
	}
	return -1;
}

        (1).直接遍历顺序表,然后 strcmp(con->arr[i].name, nammm) == 0 来判断当前联系人姓名与我们查找的联系人姓名是否相同,相同返回下标。否则返回-1。

其他查找方法:

你也可以根据其他信息来查找

(1).比如 地址 电话 这些都是以字符串形式存储的,只需修改成tel或dress即可

if (strcmp(con->arr[i].tel, nammm) == 0)
{
	return i;
}

5.2.5 DelContact() 删除联系人函数的讲解

erase()函数的讲解icon-default.png?t=N7T8https://blog.csdn.net/2301_80122797/article/details/137592121#:~:text=%E8%A6%81%E5%B0%86size%2B%2B%E3%80%82-,3.2.8%C2%A0SLErase()%20%E5%88%A0%E9%99%A4%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E5%85%83%E7%B4%A0,-%E5%A3%B0%E6%98%8E%EF%BC%9A

声明:
void DelContact(contact* con);
定义:
void DelContact(contact* con)
{
	char nn[100];
	printf("input you ready delete name\n");
	cin >> nn;
	int findd = FindContact(con, nn);
	if (findd == -1)
	{
		cout << "no name ,please reinput" << endl;
	}
	else
	{
		erase(con, findd);
		cout << "delete scussfully" << endl;
	}
}

(1).先输入要查找联系人的姓名,调用 FindContact() (查找)函数是否存在此联系人,若返回值为-1,则此联系人不存在,否则存在,调用顺序表中erase()函数,删除此联系人。

5.2.6 ShowContact() 打印通讯录函数

声明:
void ShowContact(contact* con);
定义:
void ShowContact(contact* con)
{
	printf("name  gender  age    tel   dress\n");

	for (int i = 0; i < con->size; i++)
	{
		printf("%-6s %-6s %-6d %-6s %-6s\n", con->arr[i].name, con->arr[i].gender, con->arr[i].age, con->arr[i].tel, con->arr[i].dress);

	}
	return;

}

(1).直接遍历顺序表即可,依次打印顺序表中每个成员通讯录结构体中的信息即可。

5.2.7 ModifyContact() 修改联系人信息

声明:
void ModifyContact(contact* con);
定义:
void ModifyContact(contact* con)
{
	char nemmm[100];
	printf("input name\n");
	cin >> nemmm;

	int findd = FindContact(con, nemmm);
	if (findd < 0)
	{
		printf("name if not\n");
		return;
	}
	printf("modity befor :%4s %4s %4d %4s %4s\n", con->arr[findd].name, con->arr[findd].gender, con->arr[findd].age, con->arr[findd].tel, con->arr[findd].dress);
	printf("input modity name age sex tel dress\n");
	scanf("%s%s%d%s%s", &con->arr[findd].name, &con->arr[findd].gender, &con->arr[findd].age, &con->arr[findd].tel, &con->arr[findd].dress);

	printf("modity voer :%4s %4s %4d %4s %4s\n", con->arr[findd].name, con->arr[findd].gender, con->arr[findd].age, con->arr[findd].tel, con->arr[findd].dress);

}

(1).输入要修改联系人的姓名,查找是否存在此联系人。

(2).打印修改之前的联系人信息

printf("modity befor :%4s %4s %4d %4s %4s\n", con->arr[findd].name, con->arr[findd].gender, con->arr[findd].age, con->arr[findd].tel, con->arr[findd].dress);

 (3).输入新的联系人信息

scanf("%s%s%d%s%s", &con->arr[findd].name, &con->arr[findd].gender, &con->arr[findd].age, &con->arr[findd].tel, &con->arr[findd].dress);

(4).打印修改之后联系人信息

printf("modity voer :%4s %4s %4d %4s %4s\n", con->arr[findd].name, con->arr[findd].gender, con->arr[findd].age, con->arr[findd].tel, con->arr[findd].dress);

5.2.8 DestroyContact() 销毁函数的讲解

声明:
void DestroyContact(contact* con);
定义:
void DestroyContact(contact* con)
{
	SaveContact(con);
	destort(con);
}

(1).销毁通讯录相当于销毁顺序表,只需调用顺序表中的销毁函数即可。

(2).销毁之前要先对现有数据的保存,先调用 SaveContact() 函数。

5.2.8 SaveContact() 存储数据函数

fwrite()函数的讲解icon-default.png?t=N7T8https://blog.csdn.net/2301_80122797/article/details/137268867#:~:text=%E8%BE%93%E5%87%BA%E7%BB%93%E6%9E%9C%3A-,5.2.3%20fwrite%20%3A,-size_t%20fwrite%20(

声明:
void SaveContact(contact* con);
定义:
void SaveContact(contact* con) {
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}
	//将通讯录数据写入文件
	for (int i = 0; i < con->size; i++)
	{
		fwrite(con->arr+i, sizeof(permessage), 1, pf);
	}
	printf("通讯录数据保存成功!\n");
}

(1).以二进制写的方式读取文件。

(2).使用循环将顺序表中每个结构体成员的信息存储到 contact.txt 中。

通讯录到这里就讲完啦,如果喜欢的话请给小编一个赞吧b( ̄▽ ̄)d

完结

  • 35
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值