一、题目
模拟手机通信录管理系统
主要功能有:
(1)查看功能:选择此功能,列出手机通信录得分类,如A同事、B家人、C朋友、D同学等分类,但选中某分类时,像是出此类所有数据中的姓名和电话号码;
(2)增加功能:录入新数据(包括姓名、电话号码、分类),当录入重复的姓名和电话号码时,提示结果错误并取消录入。
(3)修改功能:对选择(选择的方式自定)的联系人,修改其通信录的相关信息,但如果修改姓名,不能跟其他已有的联系人的姓名不能重复。
(4)删除功能:选择某个联系人的姓名,可对此人的相应数据进行删除。
(5)其他功能:自行分析设计有特色效果的功能,作为加分点。如:排序、分组、个人收藏、最近联系人等。
(6)要求:设计合理的数据结构,实现合理美观的操作界面。
二、效果图
-
主界面第一页
-
主界面第二页
-
我写的通讯录主要想尽力的模拟真实情况下的通讯录,首先这里我设定了一页内容只能显示三个联系人,可以通过W和S来进行一个翻页的操作,就像是我们在手机上滑上滑下浏览联系人一样,这里显示的主要是联系人姓名,我们可以输入联系人名字前的数字来访问联系人详细情况。
-
按下主界面相应联系人数字 进入联系人详情界面(这里★代表已收藏)
-
我们按下数字键后进入联系人详情界面可以看到联系人的姓名、电话、邮箱、生日、是否被收藏和分组的信息,进入联系人详情界面后我们还可以继续对当前联系人进行操作,都只要输入相应的数字键即可。
-
按下1拨打电话
-
通话界面 按下1可挂断
-
按下数字键1我们可以模拟打电话给当前联系人,同时通话结束后我们会将这个通话记录写入最近联系人中,这里的呼叫时间我用了一个随机数模拟,随机5以内的随机数,通话的过程中再次按下数字键1就可以返回刚才的界面
-
按下2可进行收藏和取消收藏的操作(这里☆代表取消收藏),这里的收藏可以随时按下,只要一按下当前页面就会做出相应的反应,刷新一次显示正确的字符,同时之后的收藏列表也会做出相应的记录。
-
按下3进入联系人修改界面
-
名字修改重名的情况
-
正常修改名字
-
名字已被修改完成 手机号修改重复
-
正常修改手机号
-
手机号修改完成 开始修改邮箱
-
邮箱修改完成 开始修改生日
-
生日修改完成 开始修改分组
-
修改后的样子
-
删除联系人(二次确认)
-
联系人被删除后 在通讯录上消失 同时人数显示减少(可以删除当前联系人,删除完后会马上进行一次保存,同时对总人数和联系人结构体数组进行更新,这样的话在通讯录显示界面就看不到被删除的联系人。)
-
姓名查找(模糊查找)
-
姓名查找找不到输入的姓名
-
手机号查找(模糊查找)
-
手机号查找找不到输入的手机号
-
姓名查找到后按下相应数字键 可进入联系人详细界面进行其他操作(手机号查找同理),查找联系人的主要方法也是模拟手机的查找,输入的信息不完全时,会输出比较符合条件的联系人,而输入信息完全找不到时,就什么都不会显示,查找完联系人后我们还可以进入联系人详细界面进行其他操作。
-
添加新联系人重名检测
-
添加新联系人重复手机号检测
-
添加新联系人成功
-
新联系人显示在通讯录中 同时人数显示加一
- 打开收藏的联系人列表 按下相应数字键可进入联系人详细界面进行其他操作
- 打开分组
- 打开“家人”分组
- 打开“朋友”分组 按下相应数字键可进入联系人详细界面进行其他操作
- 打开最近联系人 查看最近通话过的人
- 通讯录.txt中的记录的信息
三、分析
- 整体的思路主要就是通过一个结构体数组和对文件的读写来完成整个通讯录的模拟,主要的难点在于各个功能之间的协调和各个功能之间的也要保持独立性,涉及到的变量和函数比较多,运用到的数据结构主要也是一个队列,不运用链表的原因是各个联系人之间的关联性没有那么强,只要做好排序和分组即可,我们运用结构体来完成完全足以 ,我们将文件中的信息存入结构体数组中,同时对数组进行字典序排序,这里有点不足是没办法做到中文和英文混合排序,只能英文名字排序完后再对中文进行排序,排序完的结构体数组我们才进行输出,然后我们再利用写好的菜单界面来对排完序的数组进行增删查改的操作,每次操作完以后都要及时保存,同时也要对数组及时地重新排序。
四、代码
//XMUT ZRZ 2020.6.19
//jack 123456 [email protected] 1 2000 3 1 4
//rise 164459225 [email protected] 1 1999 3 5 2
//rose 134568974 [email protected] 1 2001 1 28 3
//开锁王师傅 7777776 [email protected] - 1 1995 2 6 1
//老李 2313313 [email protected] 1 1331 4 45 2
//郑润泽 1248845 [email protected] -1 2000 3 29 4
#include <iostream>
#include <vector>
#include <ctime>
#include <algorithm>
#include <unordered_map>
#include <fstream>
#include <string>
#include <cstring>
#include <cassert>
#include <windows.h>
#include <conio.h>
#include <time.h>
using namespace std;
#define page_capacity 3
typedef struct Person {
string name;
string phonenumber;
string email;
int year = 0;
int month = 0;
int day = 0;
int kind = 0;//5——家人 4——朋友 3——同事 2——同学 1——其他
int like = 0;//1——被收藏 0——没被收藏
}Person;
Person person[100],callperson[100];
int total = 0,call_total=0;
int page = 1;
int index = 0;
void AutoRead()
{
string file = "通讯录.txt";
ifstream infile;
infile.open(file.data()); //将文件流对象与文件连接起来
assert(infile.is_open()); //若失败,则输出错误消息,并终止程序运行
string s;
string name, phonenumber, email;
int year, month, day, kind, like;
char c;
infile >> name;
while ((c = infile.get()) != EOF)
{
infile >> phonenumber >> email >> like >> year >> month >> day>>kind ;
person[total].name = name;
person[total].phonenumber= phonenumber;
person[total].email = email;
person[total].year = year;
person[total].month = month;
person[total].day = day;
person[total].kind = kind;
person[total++].like = like;
//cout << "name:" << name<< endl;
//cout << "phonenumber:" << phonenumber << endl;
//cout << "email:" << email << endl;
//cout << "year:" << year << endl;
//cout << "month:" << month << endl;
//cout << "day:" << day << endl;
infile >> name;
}
infile.close(); //关闭文件输入流
}
void save()
{
ofstream outfile("通讯录.txt", ios::trunc);
for (int i = 0; i <total; i++)
{
outfile << person[i].name << " " << person[i].phonenumber << " "
<< person[i].email << " " << person[i].like << " "
<< person[i].year << " " << person[i].month << " "
<< person[i].day << " " << person[i].kind << " " << endl;
}
outfile.close();
}
int cmp(const Person& s1, const Person& s2) {
//自己定义的排序规则
return s1.name < s2.name;
}
void Sort()
{
sort(person, person + total, cmp);
}
bool NameCheck(string name) {
for (int i = 0; i < total; i++)
{
if (person[i].name == name)
return false;
}
return true;
}
bool PhonenumberCheck(string phonenumber) {
for (int i = 0; i < total; i++)
{
if (person[i].phonenumber == phonenumber)
return false;
}
return true;
}
void Call(int index)
{
system("cls");
string number = person[index].phonenumber;
string name = person[index].name;
callperson[call_total++] = person[index];
for (int i = 0; i < rand() % 5; i++)
{
cout << " " << name<<" "<<number << " " << endl;
cout << " " << "正在呼叫中" << "." << endl;
Sleep(333);
system("cls");
cout << " " << name << " " << number << " " << endl;
cout << " " << "正在呼叫中" << ".." << endl;
Sleep(333);
system("cls");
cout << " " << name << " " << number << " " << endl;
cout << " " << "正在呼叫中" << "..." << endl;
Sleep(333);
system("cls");
}
int min = 0, sec = 0;
while (1)
{
int x;
cout << " " << name << " " << number << " " << endl;
cout << " " << "正在通话中" << "..." << endl;
cout << " " << "1.挂断" << endl;
cin >> x;
if (x == 1)
break;
}
}
void Add()
{
int flag = 1;
while (flag)
{
system("cls");
string newname, newphonenumber, newemail;
int newyear, newmonth, newday, newkind;
cout << "请输入要添加的新名字:";
cin >> newname;
if (NameCheck(newname))
{
person[total].name = newname;
cout << "请输入要添加的新手机号:";
cin >> newphonenumber;
if (PhonenumberCheck(newphonenumber))
{
person[total].phonenumber = newphonenumber;
cout << "请输入要添加的新邮箱:";
cin >> newemail;
person[total].email = newemail;
cout << "请输入要添加的新生日:";
cin >> newyear >> newmonth >> newday;
person[total].year = newyear;
person[total].month = newmonth;
person[total].day = newday;
cout << "是否收藏?(1——收藏 -1——不收藏)";
int y;
cin >> y;
if (y == 1)
person[total].like = 1;
else if (y == -1)
person[total].like = -1;
cout << "请输入要添加进的分组(5——家人 4——朋友 3——同事 2——同学 1——其他 ):";
cin >> newkind;
person[total].kind = newkind;
cout << newname << " " << newphonenumber << " " << newphonenumber << " "
<< newemail << " " << newyear << " " << newmonth << " " << newday << " "
<< newkind << " " << endl;
int x;
total = total + 1;
cout << "是否继续添加? 1.继续 2.返回" << endl;
cin >> x;
if (x == 1)
continue;
else if (x == 2)
flag--;
}
else
{
cout << "该手机号已存在" << endl;
system("pause");
flag--;
}
}
else {
cout << "该名字已存在" << endl;
system("pause");
flag--;
}
}
save();
}
bool Delete(int index)
{
cout << "确认删除当前联系人?(1.确认 2.取消)" << endl;
int x;
cin >> x;
if (x == 1)
{
for (int i = index; i < total - 1; i++)
{
person[i] = person[i + 1];
}
total--;
save();
return true;
}
return false;
}
void Change(int index)
{
int flag = 1;
while (flag)
{
system("cls");
cout << "姓名:";
cout << person[index].name << endl;
cout << "电话:";
cout << person[index].phonenumber << endl;
cout << "邮箱:";
cout << person[index].email << endl;
cout << "生日:";
cout << person[index].year << "/" << person[index].month << "/" << person[index].day << endl;
cout << "是否被收藏:";
if (person[index].like == 1)
{
cout << "★" << endl;
}
else
{
cout << "☆" << endl;
}
cout << "分组:";
switch (person[index].kind)
{
case 1:cout << "其他" << endl; break;
case 2:cout << "同学" << endl; break;
case 3:cout << "同事" << endl; break;
case 4:cout << "朋友" << endl; break;
case 5:cout << "亲人" << endl; break;
}
cout << "1.修改姓名 2.修改手机号码 3.修改邮箱 4.修改生日 5.修改分组 6.退出" << endl;
int x;
string newname, newphonenumber, newemail;
int newyear, newmonth, newday, newkind;
cin >> x;
switch (x)
{
case 1: {
cout << " 请输入要修改的新名字:";
cin >> newname;
if(NameCheck(newname))
person[index].name = newname;
else
{
cout << "该名字已存在" << endl;
system("pause");
}
break;
}
case 2: {
cout << " 请输入要修改的新手机号:";
cin >> newphonenumber;
if(PhonenumberCheck(newphonenumber))
person[index].phonenumber = newphonenumber;
else
{
cout << "该手机号已存在" << endl;
system("pause");
}
break;
}
case 3: {
cout << " 请输入要修改的新邮箱:";
cin >> newemail;
person[index].email = newemail;
break;
}
case 4: {
cout << " 请输入要修改的新生日(年 月 日):";
cin >> newyear >> newmonth >> newday;
person[index].year = newyear;
person[index].month = newmonth;
person[index].day = newday;
break;
}
case 5: {
cout << " 请输入要修改的新分组(5——家人 4——朋友 3——同事 2——同学 1——其他 ):";
cin >> newkind;
person[index].kind = newkind;
break;
}
case 6: {
flag--;
break;
}
}
}
save();
}
void Query()
{
while (1)
{
int ready[100] = {
0 };
system("cls");
cout << "1.按姓名查找 2.按手机号查找 3.返回" << endl;
string temp;
int x, cnt = 0;
bool find = false;
cin >> x;
if (x == 1)
{
cout << "请输入要查找的姓名:";
cin >> temp;
for (int i = 0; i < total; i++)
{
string::size_type idx;
idx = person[i].name.find(temp);//在a中查找b.
if (idx == string::npos)//不存在
continue;
else//存在
{
ready[cnt++] = i;
find = true;
cout << cnt << "." << person[i].name << endl;
}
}
if (find) {
cout << "按下数字键查看详细(按下0取消)";
int a;
cin >> a;
if (a != 0)
{
int flag = true;
while (flag)
{
system("cls");
int x = ready[a - 1];
cout << "姓名:";
cout << person[x].name << endl;
cout << "电话:";
cout << person[x].phonenumber << endl;
cout << "邮箱:";
cout << person[x].email << endl;
cout << "生日:";
cout << person[x].year << "/" << person[x].month << "/" << person[x].day << endl;
cout << "是否被收藏:";
if (person[x].like == 1)
{
cout << "★" << endl;
}
else
{
cout << "☆" << endl;
}
cout << "分组:";
switch (person[x].kind)
{
case 1:cout << "其他" << endl; break;
case 2:cout << "同学" << endl; break;
case 3:cout << "同事" << endl; break;
case 4:cout << "朋友" << endl; break;
case 5:cout << "亲人" << endl; break;
}
cout << "1.拨号 2.收藏 3.修改 4.删除 5.返回" << endl;
int ch;
cin >> ch;
switch (ch)
{
case 1:Call(ready[a - 1]); break;
case 2:person[x].like = -person[x].like; save(); break;
case 3:Change(ready[a - 1]); flag = false; break;
case 4: {
if (Delete(ready[a - 1]))
flag = false;
break;
}
case 5:flag = false; break;
}
}
}
}
else
{
cout << "没有找到相应联系人" << endl;
system("pause");
}
}
else if (x == 2)
{
cout << "请输入要查找的手机号:" << endl;
cin >> temp;
for (int i = 0; i < total; i++)
{
string::size_type idx;
idx = person[i].phonenumber.find(temp);//在a中查找b.
if (idx == string::npos)//不存在
continue;
else//存在
{
ready[cnt++] = i;
find = true;
cout << cnt << "." << person[i].name << endl;
}
}
if (find) {
cout << "按下数字键查看详细(按下0取消)";
int a;
cin >> a;
if (a != 0)
{
int flag = true;
while (flag)
{
system("cls");
int x = ready[a - 1];
cout << "姓名:";
cout << person[x].name << endl;
cout << "电话:";
cout << person[x].phonenumber << endl;
cout << "邮箱:";
cout << person[x].email << endl;
cout << "生日:";
cout << person[x].year << "/" << person[x].month << "/" << person[x].day << endl;
cout << "是否被收藏:";
if (person[x].like == 1)
{
cout << "★" << endl;
}
else
{
cout << "☆" << endl;
}
cout << "分组:";
switch (person[x].kind)
{
case 1:cout << "其他" << endl; break;
case 2:cout << "同学" << endl; break;
case 3:cout << "同事" << endl; break;
case 4:cout << "朋友" << endl; break;
case 5:cout << "亲人" << endl; break;
}
cout << "1.拨号 2.收藏 3.修改 4.删除 5.返回" << endl;
int ch;
cin >> ch;
switch (ch)
{
case 1:Call(ready[a - 1]); break;
case 2:person[x].like = -person[x].like; save(); break;
case 3:Change(ready[a - 1]); flag = false; break;
case 4: {
if (Delete(ready[a - 1]))
flag = false;
break;
}
case 5:flag = false; break;
}
}
}
}
else
{
cout << "没有找到相应联系人" << endl;
system("pause");
}
}
else if (x == 3)
{
break;
}
else
continue;
}
}
void Collect()
{
int flag = 1;
while (flag)
{
int ready[100] = {
0 };
system("cls");
cout << "收藏列表为:" << endl;
int cnt = 0;
bool find = false;
for (int i = 0; i < total; i++)
{
if (person[i].like == 1)
{
ready[cnt++] = i;
find = true;
cout << cnt << "." << person[i].name << endl;
}
}
if (find) {
cout << "按下数字键查看详细(按下0退出)";
int a;
cin >> a;
if (a != 0)
{
int flag = true;
while (flag)
{
system("cls");
int x = ready[a - 1];
cout << "姓名:";
cout << person[x].name << endl;
cout << "电话:";
cout << person[x].phonenumber << endl;
cout << "邮箱:";
cout << person[x].email << endl;
cout << "生日:";
cout << person[x].year << "/" << person[x].month << "/" << person[x].day << endl;
cout << "是否被收藏:";
if (person[x].like == 1)
{
cout << "★" << endl;
}
else
{
cout << "☆" << endl;
}
cout << "分组:";
switch (person[x].kind)
{
case 1:cout << "其他" << endl; break;
case 2:cout << "同学" << endl; break;
case 3:cout << "同事" << endl; break;
case 4:cout << "朋友" << endl; break;
case 5:cout << "亲人" << endl; break;
}
cout << "1.拨号 2.收藏 3.修改 4.删除 5.返回" << endl;
int ch;
cin >> ch;
switch (ch)
{
case 1:Call(ready[a - 1]); break;
case 2:person[x].like = -person[x].like; save(); break;
case 3:Change(ready[a - 1]); flag = false; break;
case 4: {
if (Delete(ready[a - 1]))
flag = false;
break;
}
case 5:flag = false; break;
}
}
}
else {
flag--;
}
}
else
{
cout << "没有找到相应联系人" << endl;
system("pause");
flag--;
}
}
}
void Group()
{
int flag = 1;
int have = 1;
int pos = 0;
string which;
while (flag)
{
system("cls");
cout << "1.家人 2.朋友 3.同事 4.朋友 5.其他(按下相应数字键查看分组) 0.退出" << endl;
int x;
cin >> x;
switch (x)
{
case 1:
{
pos = 5;
which = "家人";
break;
}
case 2:
{
pos = 4;
which = "朋友";
break;
}
case 3:
{
pos = 3;
which = "同事";
break;
}
case 4:
{
pos = 2;
which = "同学";
break;
}
case 5:
{
pos = 1;
which = "其他";
break;
}
case 0:
{
flag--;
have--;
break;
}
}
if (have)
{
int ready[100] = {
0 };
system("cls");
cout << which << "列表为:" << endl;
int cnt = 0;
bool find = false;
for (int i = 0; i < total; i++)
{
if (person[i].kind == pos)
{
ready[cnt++] = i;
find = true;
cout << cnt << "." << person[i].name << endl;
}
}
if (find) {
cout << "按下数字键查看详细(按下0退出)";
int a;
cin >> a;
if (a != 0)
{
int flag = true;
while (flag)
{
system("cls");
int x = ready[a - 1];
cout << "姓名:";
cout << person[x].name << endl;
cout << "电话:";
cout << person[x].phonenumber << endl;
cout << "邮箱:";
cout << person[x].email << endl;
cout << "生日:";
cout << person[x].year << "/" << person[x].month << "/" << person[x].day << endl;
cout << "是否被收藏:";
if (person[x].like == 1)
{
cout << "★" << endl;
}
else
{
cout << "☆" << endl;
}
cout << "分组:";
switch (person[x].kind)
{
case 1:cout << "其他" << endl; break;
case 2:cout << "同学" << endl; break;
case 3:cout << "同事" << endl; break;
case 4:cout << "朋友" << endl; break;
case 5:cout << "亲人" << endl; break;
}
cout << "1.拨号 2.收藏 3.修改 4.删除 5.返回" << endl;
int ch;
cin >> ch;
switch (ch)
{
case 1:Call(ready[a - 1]); break;
case 2:person[x].like = -person[x].like; save(); break;
case 3:Change(ready[a - 1]); flag = false; break;
case 4: {
if (Delete(ready[a - 1]))
flag = false;
break;
}
case 5:flag = false; break;
}
}
}
else {
flag--;
}
}
else
{
cout << "没有找到相应联系人" << endl;
system("pause");
}
}
}
}
void Recently()
{
int flag = 1;
while (flag)
{
system("cls");
int j = 1;
int ready[100] = {
0 };
system("cls");
int cnt = 0;
bool find = false;
cout << "最近联系人列表:";
for (int i = call_total - 1; i >= 0; i--)
{
ready[cnt++] = i;
find = true;
cout << j++ << "." << callperson[i].name << " " << callperson[i].phonenumber << endl;
}
if (find) {
cout << "按下数字键回拨(按下0退出)";
int a;
cin >> a;
if (a != 0)
{
Call(ready[a - 1]);
}
else {
flag--;
}
}
else
{
cout << "没有找到相应联系人" << endl;
system("pause");
flag--;
}
}
}
void PersonPrint()
{
int a[100] = {
0};
Sort();
if (total == 0)
cout << "通讯录中无联系人" << endl;
for (int i = index; i < index+page_capacity; i++)
{
if (i == total)
break;
cout << i + 1 << ". ";
a[i]++;
cout << person[i].name << endl;
}
cout << "第" << (index / page_capacity)+1 << "页" << endl;
char c;
cin >> c;
if (c >= '0' && c <= '9')
{
if (a[c - 49])
{
bool flag = true;
while (flag)
{
system("cls");
int x = c - 49;
cout << "姓名:";
cout << person[x].name << endl;
cout << "电话:";
cout << person[x].phonenumber << endl;
cout << "邮箱:";
cout << person[x].email << endl;
cout << "生日:";
cout << person[x].year << "/" << person[x].month << "/" << person[x].day << endl;
cout << "是否被收藏:";
if (person[x].like==1)
{
cout << "★" << endl;
}
else
{
cout << "☆" << endl;
}
cout << "分组:";
switch (person[x].kind)
{
case 1:cout << "其他" << endl; break;
case 2:cout << "同学" << endl; break;
case 3:cout << "同事" << endl; break;
case 4:cout << "朋友" << endl; break;
case 5:cout << "亲人" << endl; break;
}
cout << "1.拨号 2.收藏 3.修改 4.删除 5.返回" << endl;
int ch;
cin >> ch;
switch (ch)
{
case 1:Call(c - 49); break;
case 2:person[x].like = -person[x].like; save(); break;
case 3:Change(c - 49); flag = false; break;
case 4: {
if (Delete(c - 49))
flag = false;
break;
}
case 5:flag = false; break;
}
}
}
}
else
{
switch (c)
{
case ('s'):
{
index += page_capacity;
if(index>=total)
index -= page_capacity;
break;
}
case ('w'):
{
index -= page_capacity;
if (index < 0)
index = 0;
break;
}
case ('a'):
{
Add();
break;
}
case ('q'):
{
Query();
break;
}
case ('e'):
{
Collect();
break;
}
case ('f'):
{
Group();
break;
}
case ('r'):
{
Recently();
break;
}
case ('d'):
{
save();
exit(0);
break;
}
}
}
}
void headmenu()
{
system("cls");
cout << " 欢迎使用手机通讯录" << endl;
cout << " 目前通讯录中有:" << total << "人" << endl;
cout << " q.查找 a.添加 e.收藏 f.分组 r.最近联系人 d.保存并退出" << endl;
cout << " 按下数字键打开相应联系人" << endl;
cout << " 按下字母进行相应的操作" << endl;
cout << " 按下方向键w和s来翻页" << endl;
PersonPrint();
}
int main()
{
AutoRead();
while(1)
headmenu();
}