一、作业题目
个人通讯录管理系统(2016年11月03日)
建立一通讯录,输入姓名、电话号码、住址等信息,然后对通信簿进行显示、查找、添加、修改及删除。
功能要求:
(1) 通讯录的每一条信息包括姓名、单位、固定电话、移动手机、分类(如同事、朋友、同学、家人等)、EMAIL、QQ等。
(2) 输入功能:可以一次完成若干条信息的输入。
(3) 显示功能:完成全部通讯录信息的显示(一屏最多显示10条,超过十条应能够自动分屏显示)
(4) 查找功能:可以按姓名等多种方式查找通讯信息
(5) 增加、删除、修改功能:完成通讯录信息的多种更新
二、源代码
1. 头文件
class.h
#ifndef CLASS_H
#define CLASS_H
#include<string>
using namespace std;
class Person
{
public:
string getName(){return m_sName;}
string getCompany(){return m_sCompany;}
string getMobile(){return m_sMobile;}
string getRelation(){return m_sRelation;}
string getEmail(){return m_sEmail;}
string getQQ(){return m_sQQ;}
void setName(string Name0){m_sName = Name0;}
void setCompany(string Company0){m_sCompany = Company0;}
void setMobile(string Mobile0){m_sMobile = Mobile0;}
void setRelation(string Relation0){m_sRelation = Relation0;}
void setEmail(string Email0){m_sEmail = Email0;}
void setQQ(string QQ0){m_sQQ = QQ0;}
private:
string m_sName;
string m_sCompany;
string m_sMobile;
string m_sRelation;
string m_sEmail;
string m_sQQ;
};
class Person_node
{
public:
Person data;
Person_node *next;
};
#endif
global.h
#ifndef GLOBAL_H
#define GLOBAL_H
#define SIZEMAX 20
#endif
menu.h
#ifndef MENU_H
#define MENU_H
void initPersonList(Person_node* &front,Person_node* &rear);
int add(Person_node* &front,Person_node* &rear);
int show(Person_node* &front,Person_node* &rear);
int querry(Person_node* &front,Person_node* &rear);
int set(Person_node* &front,Person_node* &rear);
int del(Person_node* &front,Person_node* &rear);
#endif
tool.h
#ifndef TOOL_H
#define TOOL_H
void initPersonList(Person_node* &front,Person_node* &rear);
int QuerryInf(Person_node* &Q,Person_node* &rear,string _sQue,int a);
#endif
2.源文件
main.cpp
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include"class.h"
#include "tool.h"
#include"menu.h"
#include"global.h"
using namespace std;
Person_node* front = NULL;
Person_node* rear = NULL;
int main()
{
initPersonList(front,rear);
int n;
do
{
printf("======欢迎进入个人通讯录管理系统!======\n");
printf("【1】新建联系人\n");
printf("【2】显示所有联系人\n");
printf("【3】查询联系人\n");
printf("【4】修改联系人\n");
printf("【5】删除联系人\n");
printf("【0】退出程序\n");
printf("请选择菜单项编号(0-5):");
scanf("%d",&n);
switch (n)
{
case 1:add(front,rear);break;
case 2:show(front,rear);break;
case 3:querry(front,rear);break;
case 4:set(front,rear);break;
case 5:del(front,rear);break;
case 0:printf("退出程序!");break;
default:printf("\n输入错误,请重新输入序号(0-5)\n\n");break;
}
}
while (n!=0);
system("pause");
return 0;
}
menu.cpp
#include<stdio.h>
#include<iostream>
#include"class.h"
#include"global.h"
#include "tool.h"
int add(Person_node* &front,Person_node* &rear)
{//返回0正常,1则不正常
string name;
string company;
string mobile;
string relation;
string email;
string qq;
Person_node* Q;
Q = front;
cout<<"【新建联系人】"<<endl;
if(rear->next == front)
{
cout<<"联系人已满!请先删除联系人!"<<endl;
return 1;
}
//以下部分可以考虑用正则表达式来实现鲁棒性
cout<<"请输入姓名:"<<endl;
cin>>name;
if (!QuerryInf(Q,rear,name,1))//判断是否存在姓名
{
cout<<"姓名已存在,返回上级菜单!"<<endl;
return 1;
}
rear->data.setName(name);
cout<<"请输入单位:"<<endl;
cin>>company;
rear->data.setCompany(company);
cout<<"请输入手机号:"<<endl;
cin>>mobile;
rear->data.setMobile(mobile);
cout<<"请输入分类:"<<endl;
cin>>relation;
rear->data.setRelation(relation);
cout<<"请输入Email:"<<endl;
cin>>email;
rear->data.setEmail(email);
cout<<"请输入QQ号:"<<endl;
cin>>qq;
rear->data.setQQ(qq);
rear = rear->next;
cout<<"新建联系人成功!"<<endl;
return 0;
}
int show(Person_node* &front,Person_node* &rear)
{//返回0正常,1则不正常
Person_node* p;
p = front;
int nCount = 0;//输出信息计数器
if(front == rear)
{
cout<<"联系人为空!"<<endl<<endl;
return 1;
}
do
{
cout << "=================================="<<endl;
cout << "姓名:" << p->data.getName()<<endl;
cout << "公司:"<< p->data.getCompany()<<endl;
cout << "手机号:" << p->data.getMobile()<<endl;
cout << "分类:" << p->data.getRelation()<<endl;
cout << "Email:" << p->data.getEmail()<<endl;
cout << "QQ:" << p->data.getQQ()<<endl;
cout << "=================================="<<endl;
p = p->next;
if (10*(nCount/10) == nCount && nCount != 0)
{//分页显示,满10条信息停一下。
cout<< "信息未显示完,按任意键继续显示。"<<endl;
system("pause");
}
nCount++;
} while (p != rear);
return 0;
}
int querry(Person_node* &front,Person_node* &rear)
{
Person_node* pQuerry;//声明一个查找指针
pQuerry = front;
int nCate;
string strQuerry;//查找的关键字
if(front == rear)
{
cout<<"联系人为空!"<<endl<<endl;
return 1;
}
do
{//依旧采用do while来实现错误输入循环
cout << "请输入需要查询的种类:"<<endl;
cout << "【1】姓名" << endl << "【2】公司" << endl << "【3】手机"
<< endl << "【4】分类"<<endl<<"【5】Email"<< endl <<"【6】QQ" << endl <<"【0】返回上级菜单"<<endl;
cin>>nCate;
switch(nCate)
{
case 1:
{
cout << "请输入需要查找的姓名:";
cin>>strQuerry;
if (QuerryInf(pQuerry,rear,strQuerry,1))
{
cout << "没有查找到相关信息!"<<endl;
return 1;
}
return 0;
}break;
case 2:
{
cout << "请输入需要查找的公司:";
cin>>strQuerry;
if (QuerryInf(pQuerry,rear,strQuerry,2))
{
cout << "没有查找到相关信息!"<<endl;
return 1;
}
return 0;
}break;
case 3:
{
cout << "请输入需要查找的手机号:";
cin>>strQuerry;
if (QuerryInf(pQuerry,rear,strQuerry,3))
{
cout << "没有查找到相关信息!"<<endl;
return 1;
}
return 0;
}break;
case 4:
{
cout << "请输入需要查找的分类:";
cin>>strQuerry;
if (QuerryInf(pQuerry,rear,strQuerry,4))
{
cout << "没有查找到相关信息!"<<endl;
return 1;
}
return 0;
}break;
case 5:
{
cout << "请输入需要查找的Email:";
cin>>strQuerry;
if (QuerryInf(pQuerry,rear,strQuerry,5))
{
cout << "没有查找到相关信息!"<<endl;
return 1;
}
return 0;
}break;
case 6:
{
cout << "请输入需要查找的QQ号:";
cin>>strQuerry;
if (QuerryInf(pQuerry,rear,strQuerry,6))
{
cout << "没有查找到相关信息!"<<endl;
return 1;
}
return 0;
}break;
case 0:return 0;break;
default:printf("\n输入错误,请重新输入序号(0-6)\n\n");break;
}
} while (nCate != 0);
return 0;
}
int set(Person_node* &front,Person_node* &rear)
{
Person_node* Q;
Q = front;
string strInput;
string name;
string company;
string mobile;
string relation;
string email;
string qq;
show(front,rear);
cout << "请输入想要修改的联系人名:";
cin >> strInput;
while(Q != rear)
{
if (strInput == Q->data.getName())
{
cout<<"姓名确定成功!"<<endl<<"请输入新姓名:"<<endl;
cin>>name;
Q->data.setName(name);
cout<<"请输入新单位:"<<endl;
cin>>company;
Q->data.setCompany(company);
cout<<"请输入新手机号:"<<endl;
cin>>mobile;
Q->data.setMobile(mobile);
cout<<"请输入新分类:"<<endl;
cin>>relation;
Q->data.setRelation(relation);
cout<<"请输入新Email:"<<endl;
cin>>email;
Q->data.setEmail(email);
cout<<"请输入新QQ号:"<<endl;
cin>>qq;
Q->data.setQQ(qq);
cout<<"=>修改成功!"<<endl;
return 0;
}
Q = Q->next;
}
cout << "没有查找到相关信息!"<<endl;
return 1;
}
int del(Person_node* &front,Person_node* &rear)
{
Person_node* Q;
Person_node* P;//暂存指针
Q = front;
string strInput;
string name;
string company;
string mobile;
string relation;
string email;
string qq;
show(front,rear);
cout << "请输入想要修改的联系人名:";
cin >> strInput;
while(Q != rear)
{
if (Q == front && strInput == Q->data.getName())
{
front = front->next;
cout<<"删除成功!"<<endl;
return 0;
}
if (strInput == Q->next->data.getName())
{
P = Q->next;
Q->next = front;
front = front->next;
Q->next->next = P->next;
cout<<"删除成功!"<<endl;
return 0;
}
Q = Q->next;
}
cout << "没有查找到相关信息!"<<endl;
return 1;
}
tool.cpp
#include<stdio.h>
#include<iostream>
#include"class.h"
#include"global.h"
Person_node person_node[SIZEMAX];
void initPersonList(Person_node* &front,Person_node* &rear)
{//采用循环队列实现链式存储,并牺牲最后一个元素空间来实现队空队满的判断。
int a = 0;
front = &person_node[0];//链表的头部
for(a = 0;a < SIZEMAX;a++)
{
if(SIZEMAX-1 == a)//一定要把值放前面,变量放后面,方便debug
person_node[a].next = &person_node[0];//链表的尾部
else
person_node[a].next = &person_node[a+1];
}
rear = &person_node[0];//链表的尾部
}
int QuerryInf(Person_node* &Q,Person_node* &rear,string _sQue,int a)
{
int i = 1;//返回值
switch(a)//1表示名字,2表示公司,3表示手机号,4表示分类,5表示Email,6表示QQ
{
case 1://姓名
{
while(Q != rear)
{
if (_sQue == Q->data.getName())
{
cout << "查找成功!"<<endl;
cout << "=================================="<<endl;
cout << "姓名:" << Q->data.getName()<<endl;
cout << "公司:"<< Q->data.getCompany()<<endl;
cout << "手机号:" << Q->data.getMobile()<<endl;
cout << "分类:" << Q->data.getRelation()<<endl;
cout << "Email:" << Q->data.getEmail()<<endl;
cout << "QQ:" << Q->data.getQQ()<<endl;
cout << "=================================="<<endl;
i = 0;
}
Q = Q->next;
}
return i;
}
case 2://公司
{
while(Q != rear)
{
if (_sQue == Q->data.getCompany())
{
cout << "查找成功!"<<endl;
cout << "=================================="<<endl;
cout << "姓名:" << Q->data.getName()<<endl;
cout << "公司:"<< Q->data.getCompany()<<endl;
cout << "手机号:" << Q->data.getMobile()<<endl;
cout << "分类:" << Q->data.getRelation()<<endl;
cout << "Email:" << Q->data.getEmail()<<endl;
cout << "QQ:" << Q->data.getQQ()<<endl;
cout << "=================================="<<endl;
i = 0;
}
Q = Q->next;
}
return i;
}
case 3://手机号
{
while(Q != rear)
{
if (_sQue == Q->data.getMobile())
{
cout << "查找成功!"<<endl;
cout << "=================================="<<endl;
cout << "姓名:" << Q->data.getName()<<endl;
cout << "公司:"<< Q->data.getCompany()<<endl;
cout << "手机号:" << Q->data.getMobile()<<endl;
cout << "分类:" << Q->data.getRelation()<<endl;
cout << "Email:" << Q->data.getEmail()<<endl;
cout << "QQ:" << Q->data.getQQ()<<endl;
cout << "=================================="<<endl;
i = 0;
}
Q = Q->next;
}
return i;
}
case 4://分类
{
while(Q != rear)
{
if (_sQue == Q->data.getRelation())
{
cout << "查找成功!"<<endl;
cout << "=================================="<<endl;
cout << "姓名:" << Q->data.getName()<<endl;
cout << "公司:"<< Q->data.getCompany()<<endl;
cout << "手机号:" << Q->data.getMobile()<<endl;
cout << "分类:" << Q->data.getRelation()<<endl;
cout << "Email:" << Q->data.getEmail()<<endl;
cout << "QQ:" << Q->data.getQQ()<<endl;
cout << "=================================="<<endl;
i = 0;
}
Q = Q->next;
}
return i;
}
case 5://Email
{
while(Q != rear)
{
if (_sQue == Q->data.getEmail())
{
cout << "查找成功!"<<endl;
cout << "=================================="<<endl;
cout << "姓名:" << Q->data.getName()<<endl;
cout << "公司:"<< Q->data.getCompany()<<endl;
cout << "手机号:" << Q->data.getMobile()<<endl;
cout << "分类:" << Q->data.getRelation()<<endl;
cout << "Email:" << Q->data.getEmail()<<endl;
cout << "QQ:" << Q->data.getQQ()<<endl;
cout << "=================================="<<endl;
i = 0;
}
Q = Q->next;
}
return i;
}
case 6://QQ
{
while(Q != rear)
{
if (_sQue == Q->data.getQQ())
{
cout << "查找成功!"<<endl;
cout << "=================================="<<endl;
cout << "姓名:" << Q->data.getName()<<endl;
cout << "公司:"<< Q->data.getCompany()<<endl;
cout << "手机号:" << Q->data.getMobile()<<endl;
cout << "分类:" << Q->data.getRelation()<<endl;
cout << "Email:" << Q->data.getEmail()<<endl;
cout << "QQ:" << Q->data.getQQ()<<endl;
cout << "=================================="<<endl;
i = 0;
}
Q = Q->next;
}
return i;
}
}
}
三、小结
C++个性课大作业可以说是相当基本的一个作业,而且操作难度不大。本想随便胡乱写一下,后来想想觉得还是有必要好好写写复习一下C++,同时不让自己手生下来。毕竟程序猿的成功秘诀是“ABC”(Always Be Coding)。当真正写下来之后发现,还是有一些收获的。
-
变量名的声明养成好的习惯。
这是第一次讲变量名定义的比较明确的一次,本以为过长的变量名会带来输入上的麻烦,但是在VS上安装了visual assist x后,这道反而是一件很方便的事情。关于C++命名的规则链接:C++命名规则 -
好的工程要有一个合适的数据结构
之前做的计费管理系统是采用普通的链表,这次用了本学期学的数据结构里面所提到的循环队列。在之后的算法设计方面也因此轻松了许多。 -
在做if判断的时候,常量一定一定要放在前面,避免出现==写成=而造成蜜汁赋值,bug找不出来。就这个bug居然折腾了一个多小时。血的教训啊。。。。
-
注意include的顺序,类的声明要放在函数的include前面,不然也会报错。
-
不足:这次里面没有涉及内存的分配管理,下次这个需要注意。在这里立个flag。算法设计不够完美,还有很多缺漏的地方;注释的使用没有规则,为了增强代码的可读性,应该规范化注释。