目录

一、实验题目

二、数据结构设计

(一)存储结构设计

(二)结点结构设计

1.通讯录数据域

2.链表

三、算法设计

(一)函数设计

    1.Read()函数

    2.Save()函数

    3.Init_LinkList()函数

    4.Create_LinkList()函数

    5.Delete_LinkList()函数

    6.Query_LinkList()函数

    7.Modify_LinkList()函数

    8.Print_LinkList()函数

    9.Compare1/2/3/4()函数

    10.Sort_LinkList()函数

    11.Clear_LinkList()函数

    12.Menu()函数

    13.Main()函数

(二)算法描述

四、完整代码

五、运行结果

1.菜单功能

2.数据读入功能

3.添加功能

4.删除功能

5.修改功能

6.查询功能

7.显示功能

8.排序功能

9.清空功能


一、实验题目

    通讯录管理系统:通讯录是用来记载和查询联系人通讯信息的工具。电子通讯录已成为手机、电子词典等电子设备中不可缺少的工具软件。请设计一个能够满足这种需求的软件。

    基本功能涵盖:输入、显示、查找、插入、删除、保存、读入、排序、修改、退出。

二、数据结构设计

(一)存储结构设计

    通讯录中的记录通常按照记载顺序先后有序,因此逻辑结构选用线性结构。考虑到本设计中经常需要进行插入和删除操作,于是物理结构采用链式结构。综上所述,本设计采用链表存储通讯记录。

(二)结点结构设计

    本设计中一条记录中涉及着较多的数据项,因此需要单独对数据域进行定义。数据域ElemType中共存储七个数据项:序号、姓名、性别、年龄、电话、地址以及分组,根据不同的数据项对其赋予合适的变量类型。LinkList指针域为一个next指针。

1.通讯录数据域

typedef struct
{
	int num;
	string name;
	string sex;
	int age;
	string telephone;
	string address;
	string relation;
}ElemType;

2.链表

typedef struct Node 
{
	ElemType data;
	struct Node* next;
}Node, * LinkList;

三、算法设计

(一)函数设计

    一共涉及十三个函数,通过这十三个函数之间的相互调用,实现通讯录管理系统的各种功能。

    1.Read()函数

    用于将文本中的记录读取到程序中,便于进行后续的操作。支持一次性读取大量的记录;

//读取功能
void Read(LinkList& L)
{
	Node* p = L;
	ifstream infile("E://book.txt", ios::in);
	int len = 0;
	infile >> len;
	ElemType tem;
	while(len--)
	{
		infile>>tem.num>>tem.name>>tem.sex>>tem.age>>tem.telephone>>tem.address>>tem.relation;
		Node* t = new Node;
		t->data = tem;
		t->next = NULL;
		p->next = t;
		p = p->next;
	}
	infile.close();
}

    2.Save()函数

    输出保存的记录的个数以及将所有记录都保存到文本中;

//存储功能
void Save(LinkList& L)
{
	Node* t = L, * cnt = L;
	ofstream outfile("E://contact.txt", ios::out);
	int len = 0;
	while(cnt->next)
	{
		len++;
		cnt = cnt->next;
	}
	outfile<<len<<endl;
	while(t)
	{
		if(t != L)
			outfile << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
		t = t->next;
	}
	outfile.close();
}

    3.Init_LinkList()函数

    初始化链表,设置头结点,并将指针指向NULL;

//初始化链表
void Init_LinkList(LinkList& L)
{
	L = new Node;
	L->next = NULL;
}

    4.Create_LinkList()函数

    首先清屏,然后新建一个结点,输入新添加的信息,设置一个对电话号码的有效性的简单验证,接着将该结点用尾插法插入链表,最后判断是否继续添加联系人;

//添加功能
void Create_LinkList(LinkList& L)
{
	system("cls");
	cout << "\t\t\t添加联系人功能" << endl;
	Node* t = L;
	int i = 1, flag = 1;
	while(t->next)
	{
		i++;
		t = t->next;
	}
	while (flag)
	{
		Node* p = new Node;
		cout<< "\t\t\t输入姓名:";
		cin>> p->data.name;
		cout<< "\t\t\t输入性别:";
		cin>> p->data.sex;
		cout<< "\t\t\t输入年龄:";
		cin>>p->data.age;
		cout<< "\t\t\t输入电话:";
		int m=1;
		while(m)
		{
			cin>>p->data.telephone;
			int n=p->data.telephone.length();
			if(n!=11)
			{
				cout<< "\t\t\t输入格式错误,请重新输入:";
				m=1;
			}
			else
			{
				for(int j=0;j<n;j++)
				{
					if(!(p->data.telephone[j]>='0' && p->data.telephone[j]<='9'))
					{
						cout<< "\t\t\t输入格式错误,请重新输入:";
						m=1;
						break;
					}
				}
				m=0;
			}
		}
		cout << "\t\t\t输入地址:";
		cin >> p->data.address;
		cout << "\t\t\t输入分组:";
		cin >> p->data.relation;
		p->data.num = i++;
		p->next = NULL;
		t->next = p;
		t = t->next;
		Save(L);
		cout << "\t\t\t成功添加一次,选择是否继续本功能(1 是 0 否)" << endl;
		cout << "\t\t\t请选择【0-1】:";
		cin >> flag;
	}
}

    5.Delete_LinkList()函数

    首先设置两种删除方式,一种是按编号删除,另一种是按姓名删除。考虑到有效性,将错误输入格式进行重新输入。接着是寻找删除结点进行删除;

//删除功能
void Delete_LinkList(LinkList& L)
{
	system("cls");
	cout << "\t\t\t删除联系人功能" << endl;
	int sel = 0;
	Node* p = L, * t = NULL;
	ElemType tem;
	cout<< "\t\t\t1.按编号删除" << endl;
	cout<< "\t\t\t2.按姓名删除" << endl;
	cout<< "\t\t\t3.返回主菜单" << endl;
	cout<< "\t\t\t请选择【1-3】:";
	cin>> sel;
	while(sel < 1 || sel>3)
	{
		cout<< "\t\t\t输入格式错误,请重新输入:";
		cin>> sel;
	}
	if(sel == 1)
	{
		int flag = 0;
		cout<< "\t\t\t请输入删除联系人的编号:";
		cin>> tem.num;
		while(p->next)
		{
			t = p->next;
			if(t->data.num == tem.num)
			{
				cout<< "\t\t\t待删除联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
			p = p->next;
		}
		if(flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		else
		{
			cout << "\t\t\t确认删除?(1 是 0 否)" << endl;
			cout << "\t\t\t请选择【0-1】:";
			cin >> sel;
			while (sel < 0 || sel>1)
			{
				cout << "\t\t\t输入格式错误,请重新输入:";
				cin >> sel;
			}
			if (sel == 0);
			else 
			{
				if (sel == 1)
				{
					p->next = t->next;
					delete t;
					cout << "\t\t\t删除成功!" << endl;
					Save(L); 
				}
			}
		}
		cout << "\n\t\t\t";
		system("pause");
		Delete_LinkList(L);
	}
	else if(sel == 2)
	{
		int flag = 0;
		cout << "\t\t\t请输入待删除联系人的姓名:";
		cin >> tem.name;
		while (p->next)
		{
			t = p->next;
			if (t->data.name == tem.name)
			{
				cout<< "\t\t\t待删除联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
			p = p->next;
		}
		if (flag == 0)
			cout << "\t\t\t该通讯录中无此人!" << endl;
		else
		{
			cout << "\t\t\t确认删除?(1 是 0 否)" << endl;
			cout << "\t\t\t请选择【0-1】:";
			cin >> sel;
			while (sel < 0 || sel>1)
			{
				cout << "\t\t\t输入格式错误,请重新输入:";
				cin >> sel;
			}
			if (sel == 0);
			else if (sel == 1)
			{
				p->next = t->next;
				delete t;
				cout << "\t\t\t删除成功!" << endl;
				Save(L); 
			}
		}
		cout << "\n\t\t\t";
		system("pause");
		Delete_LinkList(L);
	}
	else if (sel == 3) return;
}

    6.Query_LinkList()函数

    设置两种查询方式,一种是按编号查询,另一种是按姓名查;

//查询功能
void Query_LinkList(const LinkList& L)
{
	system("cls");
	cout << "\t\t\t查询联系人功能" << endl;
	int sel = 0;
	Node* t = L;
	ElemType tem;
	cout << "\t\t\t1.按编号查询" << endl;
	cout << "\t\t\t2.按姓名查询" << endl;
	cout << "\t\t\t3.返回主菜单" << endl;
	cout << "\t\t\t请选择【1-3】:";
	cin >> sel;
	while (sel < 1 || sel>3)
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	if (sel == 1)
	{
		int flag = 0;
		cout << "\t\t\t请输入待查询联系人的编号:";
		cin >> tem.num;
		while (t->next)
		{
			t = t->next;
			if (t->data.num == tem.num)
			{
				cout << "\t\t\t待查询联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
		}
		if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		cout << "\n\t\t\t";
		system("pause");
		Query_LinkList(L);
	}
	else if (sel == 2)
	{
		int flag = 0;
		cout << "\t\t\t请输入待查询联系人的姓名:";
		cin >> tem.name;
		while (t->next)
		{
			t = t->next;
			if (t->data.name == tem.name)
			{
				cout << "\t\t\t待查询联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
		}
		if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		cout << "\n\t\t\t";
		system("pause");
		Query_LinkList(L);
	}
	else if (sel == 3)
	{
		return;
	}
}

    7.Modify_LinkList()函数

    设置两种修改方式,一种是按编号修改,另一种是按姓名修改。找到位置后对其进行重新输入,修改其数据域;

//修改功能
void Modify_LinkList(LinkList& L)
{
	system("cls");
	cout << "\t\t\t修改联系人功能" << endl;
	int sel = 0;
	Node* t = L;
	ElemType tem;
	cout << "\t\t\t1.按编号修改" << endl;
	cout << "\t\t\t2.按姓名修改" << endl;
	cout << "\t\t\t3.返回主菜单" << endl;
	cout << "\t\t\t请选择【1-3】:";
	cin >> sel;
	while (sel < 1 || sel>3)
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	if (sel == 1)
	{
		int flag = 0;
		cout << "\t\t\t请输入待修改联系人的编号:";
		cin >> tem.num;
		while (t->next)
		{
			t = t->next;
			if (t->data.num == tem.num)
			{
				cout << "\t\t\t待修改联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
		}
		if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		else
		{
			ElemType tem;
			cout << "\t\t\t输入修改后的联系人信息:" << endl;
			cout << "\t\t\t输入姓名:";
			cin >> tem.name;
			cout << "\t\t\t输入性别:";
			cin >> tem.sex;
			cout << "\t\t\t输入年龄:";
			cin >> tem.age;
			cout << "\t\t\t输入电话:";
			int m=1;
			while(m)
			{
				cin>>tem.telephone;
				int n=tem.telephone.length();
				if(n!=11)
				{
					cout<< "\t\t\t输入格式错误,请重新输入:";
					m=1;
				}
				else
				{
					for(int j=0;j<n;j++)
					{
						if(!(tem.telephone[j]>='0' && tem.telephone[j]<='9'))
						{
							cout<< "\t\t\t输入格式错误,请重新输入:";
							m=1;
							break;
						}
					}
					m=0;
				}
			}
			cout << "\t\t\t输入地址:";
			cin >> tem.address;
			cout << "\t\t\t输入分组:";
			cin >> tem.relation;
			tem.num = t->data.num;
			cout << "\t\t\t确认修改?(1 是 0 否)" << endl;
			cout << "\t\t\t请选择【0-1】:";
			cin >> sel;
			while (sel < 0 || sel>1)
			{
				cout << "\t\t\t输入格式错误,请重新输入:";
				cin >> sel;
			}
			if (sel == 0);
			else if (sel == 1)
			{
				t->data = tem;
				cout << "\t\t\t修改成功!" << endl;
				Save(L); 
			}
		}
		cout << "\n\t\t\t";
		system("pause");
		Modify_LinkList(L);
	}
	else if (sel == 2)
	{
		int flag = 0;
		cout << "\t\t\t请输入待修改联系人的姓名:";
		cin >> tem.name;
		while (t->next)
		{
			t = t->next;
			if (t->data.name == tem.name)
			{
				cout << "\t\t\t待修改联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
		}
		if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		else
		{
			ElemType tem;
			cout << "\t\t\t输入修改后的联系人信息:" << endl;
			cout << "\t\t\t输入姓名:";
			cin >> tem.name;
			cout << "\t\t\t输入性别:";
			cin >> tem.sex;
			cout << "\t\t\t输入年龄:";
			cin >> tem.age;
			cout << "\t\t\t输入电话:";
			int m=1;
			while(m)
			{
				cin>>tem.telephone;
				int n=tem.telephone.length();
				if(n!=11)
				{
					cout<< "\t\t\t输入格式错误,请重新输入:";
					m=1;
				}
				else
				{
					for(int j=0;j<n;j++)
					{
						if(!(tem.telephone[j]>='0' && tem.telephone[j]<='9'))
						{
							cout<< "\t\t\t输入格式错误,请重新输入:";
							m=1;
							break;
						}
					}
					m=0;
				}
			}
			cout << "\t\t\t输入地址:";
			cin >> tem.address;
			cout << "\t\t\t输入分组:";
			cin >> tem.relation;
			tem.num = t->data.num;
			cout << "\t\t\t确认修改?(1 是 0 否)" << endl;
			cout << "\t\t\t请选择【0-1】:";
			cin >> sel;
			while (sel < 0 || sel>1)
			{
				cout << "\t\t\t输入格式错误,请重新输入:";
				cin >> sel;
			}
			if (sel == 0);
			else if (sel == 1)
			{
				t->data = tem;
				cout << "\t\t\t修改成功!" << endl;
				Save(L); 
			}
		}
		cout << "\n\t\t\t";
		system("pause");
		Delete_LinkList(L);
	}
	else if (sel == 3) return;
}

    8.Print_LinkList()函数

    从首元结点开始对数据域进行输出显示;

//显示功能
void Print_LinkList(const LinkList& L)
{
	system("cls");
	cout << "\t\t\t显示功能" << endl;
	Node* t = L->next;
	cout << "\t\t\t序号\t" << "姓名\t"<< "性别\t"<< "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
	while (t)
	{
		cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
		t = t->next;
	}
	cout << "\t\t\t";
	system("pause");
}

    9.Compare1/2/3/4()函数

    是排序中sort()函数的第三个参数,为#include<algorithm>下的自定义排序;

//排序中sort函数第三个参数
bool compare1(const ElemType& t1, const ElemType& t2)
{
	return t1.num < t2.num;
}
bool compare2(const ElemType& t1, const ElemType& t2)
{
	return t1.name < t2.name;
}
bool compare3(const ElemType& t1, const ElemType& t2)
{
	return t1.age < t2.age;
}
bool compare4(const ElemType& t1, const ElemType& t2)
{
	return t1.relation < t2.relation;
}

    10.Sort_LinkList()函数

    设置了四种排序方式,分别是按编号排序、按姓名排序、按年龄排序、按分组排序;

//排序功能
void Sort_LinkList(LinkList& L)
{
	system("cls");
	cout << "\t\t\t排序功能" << endl;
	Node* p = L;
	cout << "\t\t\t1.按编号排序" << endl;
	cout << "\t\t\t2.按姓名排序" << endl;
	cout << "\t\t\t3.按年龄排序" << endl;
	cout << "\t\t\t4.按分组排序" << endl;
	cout << "\t\t\t5.返回主菜单" << endl;
	cout << "\t\t\t请选择【1-5】:";
	int cnt = 0, i = 0;
	int sel;
	cin>>sel;
	while (sel < 1 || sel > 5)
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	while (p->next)
	{
		p = p->next;
		cnt++;
	}
	ElemType* arr = new ElemType[cnt];
	p = L;
	while (p->next)
	{
		p = p->next;
		arr[i++] = p->data;
	}
	if(sel==1)
	{
		sort(arr, arr + cnt, compare1);
	}
	else if(sel==2)
	{
		sort(arr, arr + cnt, compare2);
	}
	else if(sel==3)
	{
		sort(arr, arr + cnt, compare3);
	}
	else if(sel==4)
	{
		sort(arr, arr + cnt, compare4);
	}
	else if(sel==5) return;
	p = L, i = 0;
	while (p->next)
	{
		p = p->next;
		p->data = arr[i++];
		p->data.num = i;
	}
	cout << "\t\t\t对通讯录进行排序并整理如下:" << endl;
	Node* t = L->next;
	cout << "\t\t\t序号\t" << "姓名\t" <<"性别\t" <<"年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
	while (t)
	{
		cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
		t = t->next;
	}
	Save(L);
	cout << "\n\t\t\t";
	system("pause");
	Sort_LinkList(L);
}

    11.Clear_LinkList()函数

    清空链表,但是头结点还存在;

//清空功能
void Clear_LinkList(LinkList& L)
{
	int sel = 0;
	system("cls");
	cout << "\t\t\t清空功能" << endl;
	cout << "\t\t\t1 确认清空通讯录" << endl;
	cout << "\t\t\t2 返回主菜单" << endl;
	cout << "\t\t\t请选择【1-2】:";
	cin >> sel;
	while (sel < 1 || sel>2)
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	if (sel == 1)
	{
		Node* head = L;
		if (head == NULL)
		{
			return;
		}
		Node* curNode = head->next;
		while (curNode != NULL)
		{
			Node* nextNode = curNode->next;
			free(curNode);
			curNode = nextNode;
		}
		head->next = NULL;
		Save(L);
		cout << "\n\t\t\t";
		system("pause");
	}
	else if (sel == 2) return;
}

    12.Menu()函数

    菜单功能,对本设计的共八种功能进行调用;

//菜单功能
void menu(LinkList& L)
{
	char sel;
	system("cls");
	cout << "\t\t\t通讯录管理系统" << endl;
	cout << "\t\t\t你可以进行以下操作:" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             1.添加联系人               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             2.删除联系人               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             3.修改联系人               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             4.查询联系人               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             5.通讯录显示               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             6.通讯录排序               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             7.通讯录清空               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             0.退出                     |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t请选择【0-7】:";
	cin >> sel;
	while (sel < '0' || sel>'7')
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	switch (sel)
	{
	case '1':
		Create_LinkList(L);
		menu(L);
		break;
	case '2':
		Delete_LinkList(L);
		menu(L);
		break;
	case '3':
		Modify_LinkList(L);
		menu(L);
		break;
	case '4':
		Query_LinkList(L);
		menu(L);
		break;
	case '5':
		Print_LinkList(L);
		menu(L);
		break;
	case '6':
		Sort_LinkList(L);
		menu(L);
		break;
	case '7':
		Clear_LinkList(L);
		menu(L);
		break;
	case '0':
		exit(0);
	default:
		menu(L);
	}
}

    13.Main()函数

    主函数,对各个函数调用实现通讯录管理系统的各种功能。

//主函数
int main()
{
	system("color 71");
	LinkList L;
	Init_LinkList(L);
	Read(L);
	menu(L);
	return 0;
}

(二)算法描述

    算法思想:

    通讯录管理系统要实现输入、显示、查找、插入、删除、保存、读入、排序、修改、退出的基本功能。因此总体考虑下,由一个主函数和若干个函数构成。主函数主要负责对各个函数的联合调用,实现通讯录管理系统的各个功能,其他函数则对应着不同的功能,将一个功能封装成一个函数,对应实施。

    读入功能:设置指针p从头结点开始,先将文本book.txt中的第一行内容导入。再通过len控制导入次数,实现将文本中的数据逐个读入,中间变量指针tem、t。最后关闭文本。

    保存功能:将指针t指向链表L的头结点,打开待存入的文本,通过指针cnt以及int变量len从首元结点扫描到尾结点,计算出链表的长度,并存入文本。在while的循环下从首元结点开始到尾结点,逐个结点地将数据域保存在文本中。

    初始化链表:建立头结点,将头结点的指针指向NULL。

    插入功能:首先利用system("cls")进行清屏,接着开始利用t指针和i变量,统计出当前的链表长度。设置标志位flag控制添加的次数,将姓名、性别、年龄等信息逐个输入。在当前输入中设置了一个输入数据有效性检验,对输入的电话号码进行简单的判断,确认其有效性,若格式存在问题,则重新输入。将该结点尾插法插入链表中,并进行下一次的判断,继续添加还是退出。

    删除功能:设置两种删除的方式,一种是按照编号删除,另一种是按照姓名删除。对输入的选择进行有效性检验,若不满足则重新输入。当sel等于1的时候,对链表进行遍历操作,若找到了与编号相等的数据,则现将其输出。利用flag标志位判断是否找到,若找到,则再次确认是否确定删除,通过将p指针指向t指针的下一个结点,先将t结点从链表中去除,再用delete删除。第二种方法与第一种方法思路基本相似,只是在编号的地方改成了姓名。

    查找功能:查找功能与删除功能大致相同,不同点在于只需找到即可,不需要再执行删除功能。

    修改功能:修改功能与删除功能大致相同,不同点在于在找到之后,将删除功能改为了修改。在数据域的输入中,设置了有效性的检验,对电话号码的有效性进行了简单的检验,若格式错误,需要重新输入操作。且设置了一个sel位,判断是否决定修改,更加贴合现实。

    显示功能:直接从首元结点开始遍历,将每个结点的数据域输出。

    排序功能:设置四种方式的排序方法,一种是按编号排序、一种是按姓名排序、一种是按年龄排序还有一种是按分组排序。设置指针p和int类型变量cnt,统计出链表的长度。设置数据域类型数组,得到排序的起始位置。利用自定义sort()进行排序,根据sel选择不同的排序要求。再将排序后的数组重新装回链表。最后进行输出显示排序后的结果。

    清空功能:当sel等于1时,实现清空功能。首先判断通讯录中是否存在记录,接着将curNode结点指向首元结点,并将其的下一个结点赋给nextNode,用free()将curNode结点销毁。循环执行,直至链表成为空链表。

    菜单功能:将几种功能显示出来,并标上编号,以供选择。通过“-|”修饰菜单,使其起美化效果。对sel的输入进行有效性检验,若输入不符合规范,进行重新输入。通过switch()对选择的功能函数进行调用。

    主函数:为起修饰性作用,system(“color 71”)用来美化字体和背景。首先创建链表,然后将文本中的数据读入系统,接着实现通讯录的管理系统的各种功能。

    以上是各个功能模块的实现思路,将其一一编写出,即可最终实现通讯管理系统。

四、完整代码

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<fstream>
using namespace std;
//通讯录数据元素
typedef struct
{
	int num;
	string name;
	string sex;
	int age;
	string telephone;
	string address;
	string relation;
}ElemType;
//链表
typedef struct Node 
{
	ElemType data;
	struct Node* next;
}Node, * LinkList;
//读取功能
void Read(LinkList& L)
{
	Node* p = L;
	ifstream infile("E://book.txt", ios::in);
	int len = 0;
	infile >> len;
	ElemType tem;
	while(len--)
	{
		infile>>tem.num>>tem.name>>tem.sex>>tem.age>>tem.telephone>>tem.address>>tem.relation;
		Node* t = new Node;
		t->data = tem;
		t->next = NULL;
		p->next = t;
		p = p->next;
	}
	infile.close();
}
//存储功能
void Save(LinkList& L)
{
	Node* t = L, * cnt = L;
	ofstream outfile("E://contact.txt", ios::out);
	int len = 0;
	while(cnt->next)
	{
		len++;
		cnt = cnt->next;
	}
	outfile<<len<<endl;
	while(t)
	{
		if(t != L)
			outfile << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
		t = t->next;
	}
	outfile.close();
}
//初始化链表
void Init_LinkList(LinkList& L)
{
	L = new Node;
	L->next = NULL;
}
//添加功能
void Create_LinkList(LinkList& L)
{
	system("cls");
	cout << "\t\t\t添加联系人功能" << endl;
	Node* t = L;
	int i = 1, flag = 1;
	while(t->next)
	{
		i++;
		t = t->next;
	}
	while (flag)
	{
		Node* p = new Node;
		cout<< "\t\t\t输入姓名:";
		cin>> p->data.name;
		cout<< "\t\t\t输入性别:";
		cin>> p->data.sex;
		cout<< "\t\t\t输入年龄:";
		cin>>p->data.age;
		cout<< "\t\t\t输入电话:";
		int m=1;
		while(m)
		{
			cin>>p->data.telephone;
			int n=p->data.telephone.length();
			if(n!=11)
			{
				cout<< "\t\t\t输入格式错误,请重新输入:";
				m=1;
			}
			else
			{
				for(int j=0;j<n;j++)
				{
					if(!(p->data.telephone[j]>='0' && p->data.telephone[j]<='9'))
					{
						cout<< "\t\t\t输入格式错误,请重新输入:";
						m=1;
						break;
					}
				}
				m=0;
			}
		}
		cout << "\t\t\t输入地址:";
		cin >> p->data.address;
		cout << "\t\t\t输入分组:";
		cin >> p->data.relation;
		p->data.num = i++;
		p->next = NULL;
		t->next = p;
		t = t->next;
		Save(L);
		cout << "\t\t\t成功添加一次,选择是否继续本功能(1 是 0 否)" << endl;
		cout << "\t\t\t请选择【0-1】:";
		cin >> flag;
	}
}
//删除功能
void Delete_LinkList(LinkList& L)
{
	system("cls");
	cout << "\t\t\t删除联系人功能" << endl;
	int sel = 0;
	Node* p = L, * t = NULL;
	ElemType tem;
	cout<< "\t\t\t1.按编号删除" << endl;
	cout<< "\t\t\t2.按姓名删除" << endl;
	cout<< "\t\t\t3.返回主菜单" << endl;
	cout<< "\t\t\t请选择【1-3】:";
	cin>> sel;
	while(sel < 1 || sel>3)
	{
		cout<< "\t\t\t输入格式错误,请重新输入:";
		cin>> sel;
	}
	if(sel == 1)
	{
		int flag = 0;
		cout<< "\t\t\t请输入删除联系人的编号:";
		cin>> tem.num;
		while(p->next)
		{
			t = p->next;
			if(t->data.num == tem.num)
			{
				cout<< "\t\t\t待删除联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
			p = p->next;
		}
		if(flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		else
		{
			cout << "\t\t\t确认删除?(1 是 0 否)" << endl;
			cout << "\t\t\t请选择【0-1】:";
			cin >> sel;
			while (sel < 0 || sel>1)
			{
				cout << "\t\t\t输入格式错误,请重新输入:";
				cin >> sel;
			}
			if (sel == 0);
			else 
			{
				if (sel == 1)
				{
					p->next = t->next;
					delete t;
					cout << "\t\t\t删除成功!" << endl;
					Save(L); 
				}
			}
		}
		cout << "\n\t\t\t";
		system("pause");
		Delete_LinkList(L);
	}
	else if(sel == 2)
	{
		int flag = 0;
		cout << "\t\t\t请输入待删除联系人的姓名:";
		cin >> tem.name;
		while (p->next)
		{
			t = p->next;
			if (t->data.name == tem.name)
			{
				cout<< "\t\t\t待删除联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
			p = p->next;
		}
		if (flag == 0)
			cout << "\t\t\t该通讯录中无此人!" << endl;
		else
		{
			cout << "\t\t\t确认删除?(1 是 0 否)" << endl;
			cout << "\t\t\t请选择【0-1】:";
			cin >> sel;
			while (sel < 0 || sel>1)
			{
				cout << "\t\t\t输入格式错误,请重新输入:";
				cin >> sel;
			}
			if (sel == 0);
			else if (sel == 1)
			{
				p->next = t->next;
				delete t;
				cout << "\t\t\t删除成功!" << endl;
				Save(L); 
			}
		}
		cout << "\n\t\t\t";
		system("pause");
		Delete_LinkList(L);
	}
	else if (sel == 3) return;
}
//查询功能
void Query_LinkList(const LinkList& L)
{
	system("cls");
	cout << "\t\t\t查询联系人功能" << endl;
	int sel = 0;
	Node* t = L;
	ElemType tem;
	cout << "\t\t\t1.按编号查询" << endl;
	cout << "\t\t\t2.按姓名查询" << endl;
	cout << "\t\t\t3.返回主菜单" << endl;
	cout << "\t\t\t请选择【1-3】:";
	cin >> sel;
	while (sel < 1 || sel>3)
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	if (sel == 1)
	{
		int flag = 0;
		cout << "\t\t\t请输入待查询联系人的编号:";
		cin >> tem.num;
		while (t->next)
		{
			t = t->next;
			if (t->data.num == tem.num)
			{
				cout << "\t\t\t待查询联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
		}
		if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		cout << "\n\t\t\t";
		system("pause");
		Query_LinkList(L);
	}
	else if (sel == 2)
	{
		int flag = 0;
		cout << "\t\t\t请输入待查询联系人的姓名:";
		cin >> tem.name;
		while (t->next)
		{
			t = t->next;
			if (t->data.name == tem.name)
			{
				cout << "\t\t\t待查询联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
		}
		if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		cout << "\n\t\t\t";
		system("pause");
		Query_LinkList(L);
	}
	else if (sel == 3)
	{
		return;
	}
}
//修改功能
void Modify_LinkList(LinkList& L)
{
	system("cls");
	cout << "\t\t\t修改联系人功能" << endl;
	int sel = 0;
	Node* t = L;
	ElemType tem;
	cout << "\t\t\t1.按编号修改" << endl;
	cout << "\t\t\t2.按姓名修改" << endl;
	cout << "\t\t\t3.返回主菜单" << endl;
	cout << "\t\t\t请选择【1-3】:";
	cin >> sel;
	while (sel < 1 || sel>3)
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	if (sel == 1)
	{
		int flag = 0;
		cout << "\t\t\t请输入待修改联系人的编号:";
		cin >> tem.num;
		while (t->next)
		{
			t = t->next;
			if (t->data.num == tem.num)
			{
				cout << "\t\t\t待修改联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
		}
		if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		else
		{
			ElemType tem;
			cout << "\t\t\t输入修改后的联系人信息:" << endl;
			cout << "\t\t\t输入姓名:";
			cin >> tem.name;
			cout << "\t\t\t输入性别:";
			cin >> tem.sex;
			cout << "\t\t\t输入年龄:";
			cin >> tem.age;
			cout << "\t\t\t输入电话:";
			int m=1;
			while(m)
			{
				cin>>tem.telephone;
				int n=tem.telephone.length();
				if(n!=11)
				{
					cout<< "\t\t\t输入格式错误,请重新输入:";
					m=1;
				}
				else
				{
					for(int j=0;j<n;j++)
					{
						if(!(tem.telephone[j]>='0' && tem.telephone[j]<='9'))
						{
							cout<< "\t\t\t输入格式错误,请重新输入:";
							m=1;
							break;
						}
					}
					m=0;
				}
			}
			cout << "\t\t\t输入地址:";
			cin >> tem.address;
			cout << "\t\t\t输入分组:";
			cin >> tem.relation;
			tem.num = t->data.num;
			cout << "\t\t\t确认修改?(1 是 0 否)" << endl;
			cout << "\t\t\t请选择【0-1】:";
			cin >> sel;
			while (sel < 0 || sel>1)
			{
				cout << "\t\t\t输入格式错误,请重新输入:";
				cin >> sel;
			}
			if (sel == 0);
			else if (sel == 1)
			{
				t->data = tem;
				cout << "\t\t\t修改成功!" << endl;
				Save(L); 
			}
		}
		cout << "\n\t\t\t";
		system("pause");
		Modify_LinkList(L);
	}
	else if (sel == 2)
	{
		int flag = 0;
		cout << "\t\t\t请输入待修改联系人的姓名:";
		cin >> tem.name;
		while (t->next)
		{
			t = t->next;
			if (t->data.name == tem.name)
			{
				cout << "\t\t\t待修改联系人信息如下:" << endl;
				cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
				cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
				flag = 1;
				break;
			}
		}
		if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
		else
		{
			ElemType tem;
			cout << "\t\t\t输入修改后的联系人信息:" << endl;
			cout << "\t\t\t输入姓名:";
			cin >> tem.name;
			cout << "\t\t\t输入性别:";
			cin >> tem.sex;
			cout << "\t\t\t输入年龄:";
			cin >> tem.age;
			cout << "\t\t\t输入电话:";
			int m=1;
			while(m)
			{
				cin>>tem.telephone;
				int n=tem.telephone.length();
				if(n!=11)
				{
					cout<< "\t\t\t输入格式错误,请重新输入:";
					m=1;
				}
				else
				{
					for(int j=0;j<n;j++)
					{
						if(!(tem.telephone[j]>='0' && tem.telephone[j]<='9'))
						{
							cout<< "\t\t\t输入格式错误,请重新输入:";
							m=1;
							break;
						}
					}
					m=0;
				}
			}
			cout << "\t\t\t输入地址:";
			cin >> tem.address;
			cout << "\t\t\t输入分组:";
			cin >> tem.relation;
			tem.num = t->data.num;
			cout << "\t\t\t确认修改?(1 是 0 否)" << endl;
			cout << "\t\t\t请选择【0-1】:";
			cin >> sel;
			while (sel < 0 || sel>1)
			{
				cout << "\t\t\t输入格式错误,请重新输入:";
				cin >> sel;
			}
			if (sel == 0);
			else if (sel == 1)
			{
				t->data = tem;
				cout << "\t\t\t修改成功!" << endl;
				Save(L); 
			}
		}
		cout << "\n\t\t\t";
		system("pause");
		Delete_LinkList(L);
	}
	else if (sel == 3) return;
}
//显示功能
void Print_LinkList(const LinkList& L)
{
	system("cls");
	cout << "\t\t\t显示功能" << endl;
	Node* t = L->next;
	cout << "\t\t\t序号\t" << "姓名\t"<< "性别\t"<< "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
	while (t)
	{
		cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
		t = t->next;
	}
	cout << "\t\t\t";
	system("pause");
}
//排序中sort函数第三个参数
bool compare1(const ElemType& t1, const ElemType& t2)
{
	return t1.num < t2.num;
}
bool compare2(const ElemType& t1, const ElemType& t2)
{
	return t1.name < t2.name;
}
bool compare3(const ElemType& t1, const ElemType& t2)
{
	return t1.age < t2.age;
}
bool compare4(const ElemType& t1, const ElemType& t2)
{
	return t1.relation < t2.relation;
}
//排序功能
void Sort_LinkList(LinkList& L)
{
	system("cls");
	cout << "\t\t\t排序功能" << endl;
	Node* p = L;
	cout << "\t\t\t1.按编号排序" << endl;
	cout << "\t\t\t2.按姓名排序" << endl;
	cout << "\t\t\t3.按年龄排序" << endl;
	cout << "\t\t\t4.按分组排序" << endl;
	cout << "\t\t\t5.返回主菜单" << endl;
	cout << "\t\t\t请选择【1-5】:";
	int cnt = 0, i = 0;
	int sel;
	cin>>sel;
	while (sel < 1 || sel > 5)
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	while (p->next)
	{
		p = p->next;
		cnt++;
	}
	ElemType* arr = new ElemType[cnt];
	p = L;
	while (p->next)
	{
		p = p->next;
		arr[i++] = p->data;
	}
	if(sel==1)
	{
		sort(arr, arr + cnt, compare1);
	}
	else if(sel==2)
	{
		sort(arr, arr + cnt, compare2);
	}
	else if(sel==3)
	{
		sort(arr, arr + cnt, compare3);
	}
	else if(sel==4)
	{
		sort(arr, arr + cnt, compare4);
	}
	else if(sel==5) return;
	p = L, i = 0;
	while (p->next)
	{
		p = p->next;
		p->data = arr[i++];
		p->data.num = i;
	}
	cout << "\t\t\t对通讯录进行排序并整理如下:" << endl;
	Node* t = L->next;
	cout << "\t\t\t序号\t" << "姓名\t" <<"性别\t" <<"年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
	while (t)
	{
		cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
		t = t->next;
	}
	Save(L);
	cout << "\n\t\t\t";
	system("pause");
	Sort_LinkList(L);
}
//清空功能
void Clear_LinkList(LinkList& L)
{
	int sel = 0;
	system("cls");
	cout << "\t\t\t清空功能" << endl;
	cout << "\t\t\t1 确认清空通讯录" << endl;
	cout << "\t\t\t2 返回主菜单" << endl;
	cout << "\t\t\t请选择【1-2】:";
	cin >> sel;
	while (sel < 1 || sel>2)
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	if (sel == 1)
	{
		Node* head = L;
		if (head == NULL)
		{
			return;
		}
		Node* curNode = head->next;
		while (curNode != NULL)
		{
			Node* nextNode = curNode->next;
			free(curNode);
			curNode = nextNode;
		}
		head->next = NULL;
		Save(L);
		cout << "\n\t\t\t";
		system("pause");
	}
	else if (sel == 2) return;
}
//菜单功能
void menu(LinkList& L)
{
	char sel;
	system("cls");
	cout << "\t\t\t通讯录管理系统" << endl;
	cout << "\t\t\t你可以进行以下操作:" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             1.添加联系人               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             2.删除联系人               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             3.修改联系人               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             4.查询联系人               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             5.通讯录显示               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             6.通讯录排序               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             7.通讯录清空               |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t|             0.退出                     |" << endl;
	cout << "\t\t\t|----------------------------------------|" << endl;
	cout << "\t\t\t请选择【0-7】:";
	cin >> sel;
	while (sel < '0' || sel>'7')
	{
		cout << "\t\t\t输入格式错误,请重新输入:";
		cin >> sel;
	}
	switch (sel)
	{
	case '1':
		Create_LinkList(L);
		menu(L);
		break;
	case '2':
		Delete_LinkList(L);
		menu(L);
		break;
	case '3':
		Modify_LinkList(L);
		menu(L);
		break;
	case '4':
		Query_LinkList(L);
		menu(L);
		break;
	case '5':
		Print_LinkList(L);
		menu(L);
		break;
	case '6':
		Sort_LinkList(L);
		menu(L);
		break;
	case '7':
		Clear_LinkList(L);
		menu(L);
		break;
	case '0':
		exit(0);
	default:
		menu(L);
	}
}
//主函数
int main()
{
	system("color 71");
	LinkList L;
	Init_LinkList(L);
	Read(L);
	menu(L);
	return 0;
}

五、运行结果

1.菜单功能

2.数据读入功能

3.添加功能

4.删除功能

5.修改功能

6.查询功能

7.显示功能

8.排序功能

9.清空功能

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐