您的位置:首页 > 其它

用户登录系统(平衡树AVLTree实现)(一)

2018-03-24 15:50 381 查看
/*【问题描述】在登录服务器系统时,都需要验证用户名和密码,如telnet远程登录服务器。
用户输入用户名和密码后,服务器程序会首先验证用户信息的合法性。由于用户信息的验证频率很高,
系统有必要有效地组织这些用户信息,从而快速查找和验证用户。另外,系统也会经常会添加新用户、
删除老用户和更新用户密码等操作,因此,系统必须采用动态结构,在添加、删除或更新后,
依然能保证验证过程的快速。请采用相应的数据结构模拟用户登录系统,其功能要求包括用户登录、用户密码更新、
用户添加和用户删除等。
【基本要求】
1.要求自己编程实现二叉树结构及其相关功能,以存储用户信息,不允许使用标准模板类的二叉树结构和函数。
同时要求根据二叉树的变化情况,进行相应的平衡操作,即AVL平衡树操作,四种平衡操作都必须考虑。
测试时,各种情况都需要测试,并附上测试截图;
2.要求采用类的设计思路,不允许出现类以外的函数定义,但允许友元函数。主函数中只能出现类的成员函数的调用,
不允许出现对其它函数的调用。
3.要求采用多文件方式:.h文件存储类的声明,.cpp文件存储类的实现,
主函数main存储在另外一个单独的cpp文件中。如果采用类模板,则类的声明和实现都放在.h文件中。
4.不强制要求采用类模板,也不要求采用可视化窗口;要求源程序中有相应注释;
5.要求测试例子要比较详尽,各种极限情况也要考虑到,测试的输出信息要详细易懂,表明各个功能的执行正确;
6.要求采用Visual C++ 6.0及以上版本进行调试;

【实现提示】
1.用户信息(即用户名和密码)可以存储在文件中,当程序启动时,从文件中读取所有的用户信息,
并建立合适的查找二叉树;
2.验证过程时,需要根据登录的用户名,检索整个二叉树,找到匹配的用户名,进行验证;更新用户密码时,
也需要检索二叉树,找到匹配项后进行更新,同时更新文件中存储的用户密码。
3.添加用户时,不仅需要在文件中添加,也需要在二叉树中添加相应的节点;删除用户时,也是如此;
【运行结果要求】要求能够实现用户登录验证、添加用户、删除用户和更新用户密码功能,
实验报告要求有详细的功能测试截图。
*/
//-----------------------------------AVLTree.h-----------------------------------------
#include<iostream>
#include<iomanip>

#ifndef AVLTREE
#define AVLTREE

#define LH +1 //左高
#define EH 0  //等高
#define RH -1 //右高

template<typename DataType>
class  AVLTree//定义一个AVLTree类
{
public:
//-------------------------------------------------------------------------
/*** 此板块是AVLTree的基本功能函数 ***/

AVLTree();//构造函数
~AVLTree();//析构函数
AVLTree(const AVLTree & orginal);//复制构造函数
const AVLTree & operator=(const AVLTree & rightHandSide);//赋值构造函数
bool empty() const;//判空函数
//--------------------------------------------------------------------------
/*** 此板块是AVLTree的主要功能函数 ***/

bool search(const DataType & item) const;//查找函数(用户登录)(查找用户名与密码)
bool searchExtra(const DataType & item) const;//额外查找函数(用户名是否注册)(查找用户名)
void insert(const DataType & item);//插入函数(注册新用户)
void remove(const DataType & item);//删除函数(注销用户信息)
void modify(const DataType & item) ;//修改函数(修改用户密码)
//--------------------------------------------------------------------------
/*** 此板块是AVLTree的输出功能函数 ***/

void inorder(ostream & out) const;//中序遍历函数(查看用户信息)
void graph(ostream & out) const;//图形输出(查看用户信息)
//--------------------------------------------------------------------------------
private:
class BinNode//定义一个BinNode类
{
public:
DataType data;//结点数据
BinNode *left;//左指针
BinNode *right;//右指针
int bf;//平衡因子

BinNode()//默认构造函数
:left(0),right(0),bf(0)
{}

BinNode(const DataType & item,BinNode *lt=0,BinNode *rt=0,int b=0)//显式构造函数
:data(item),left(lt),right(rt),bf(b)
{}
};

typedef BinNode *BinNodePointer;
//-----------------------------------------------------------------------------
/*** 此板块主要完成AVLTree的删除,遍历,输出 ***/

void destroyAux(BinNodePointer & t);//析构AVLTree辅助函数
void inorderAux(ostream & out,BinNodePointer subtreePtr) const;//中序遍历辅助函数
void graphAux(ostream & out,int indent,BinNodePointer subtreeRoot) const;//图形输出辅助函数
//-----------------------------------------------------------------------------
/*** 此板块主要完成AVLTree结点的插入,删除 ***/

void L_Rotate(BinNodePointer & p);//左旋(逆时针旋转)
void R_Rotate(BinNodePointer & p);//右旋(顺时针旋转)
void leftBalance(BinNodePointer & t);//左平衡处理
void rightBalance(BinNodePointer & t);//右平衡处理
bool insertAux(BinNodePointer & t,const DataType & item, bool & taller);//插入叶节点辅助函数
bool deleteAux(BinNodePointer & t, DataType item, bool & shorter);//删除叶节点辅助函数

//int* clone(BinNodePointer t) const;//克隆二叉树(方法一)
//BinNode* cloneTree(BinNode *root);//克隆二叉树(方法二)

BinNodePointer myRoot;//AVLTree的树根
};

/*** 此板块是AVLTree的基本功能函数 ***/

template<typename DataType>//构造函数------------------------------
inline AVLTree<DataType>::AVLTree()
:myRoot(0)
{}

template<typename DataType>//析构函数-------------------------------
inline AVLTree<DataType>::~AVLTree()
{
destroyAux(myRoot);//调用析构AVLTree辅助函数
}

template<typename DataType>//析构AVLTree辅助函数--------------------
void AVLTree<DataType>::destroyAux(BinNodePointer & t)
{
if(t)
{
destroyAux(t->left);//销毁左子树
destroyAux(t->right);//销毁右子树
delete t;//删除节点t
t=0;//将t置空
}
}

template<typename DataType>//复制构造函数--------------------------
inline AVLTree<DataType>::AVLTree(const AVLTree & original)
:myRroot(0)
{
*this=original;//调用赋值构造函数
}

template<typename DataType>//赋值构造函数-------------------------
inline const AVLTree<DataType> & AVLTree<DataType>::operator=(const AVLTree & rightHandSide)
{
if(this!=& rightHandSide)//不是自我赋值
{
destroyAux(myRoot);//销毁原树
myRoot=clone(rightHandSide.myRoot);//克隆右值
}
return *this;
}
//--------------------------------------------------
/*** 以下是克隆AVLTree的两种实现方法,暂时未用到 ***/

/*template<typename DataType>//克隆二叉树(方法一)
int* AVLTree<DataType>::clone(BinNode* t) const
{
if(t==0)
return 0;
return new BinNode(t->data,clone(t->left),clone(t->right),t->bf);
} */

/*template<typename DataType>//克隆二叉树(方法二)
BinNode* AVLTree<DataType>::cloneTree(BinNode* root)
{
if(root==0) return 0;
TreeNode *newroot=new TreeNode(root->data,root->bf);
newroot->left=cloneTree(root->left);
newroot->right=cloneTree(root->right);
return newroot;
} */

template<typename DataType>//判空函数------------------------------
inline bool AVLTree<DataType>::empty() const
{
return myRoot==0;
}

/*** 此板块是AVLTree的主要功能函数 ***/

template<typename DataType>//查找函数(循环版本)--------------------
bool AVLTree<DataType>::search(const DataType & item) const
{
BinNodePointer locptr=myRoot;
bool found=false;
while(!found && locptr!=0)//查找用户名以及密码
{
if(item<locptr->data)//左子树查找
locptr=locptr->left;
else if(locptr->data<item)//右子树查找
locptr=locptr->right;
else
found=true;
}
return found;//返回found
}

template<typename DataType>//额外查找函数(循环版本)----------------
bool AVLTree<DataType>::searchExtra(const DataType & item) const
{
BinNodePointer locptr=myRoot;
bool found=false;
while(!found && locptr!=0)//查找用户名
{
if(locptr->data>item)//左子树查找
locptr=locptr->left;
else if(item>locptr->data)//右子树查找
locptr=locptr->right;
else
found=true;
}
return found;//返回found
}

template<typename DataType>//插入函数-------------------------------
void AVLTree<DataType>::insert(const DataType & item)
{
bool taller=false;
insertAux(myRoot,item,taller);//调用辅助插入函数
}

template<typename DataType>//删除函数-------------------------------
void AVLTree<DataType>::remove(const DataType & item)
{
bool shorter=false;
deleteAux(myRoot,item,shorter);//调用辅助删除函数
}

template<typename DataType>//修改函数(修改用户密码)------------------
void AVLTree<DataType>::modify(const DataType & item)
{
BinNodePointer locptr=myRoot;
bool found=false;
while(!found && locptr!=0)//查找用户名
{
if(locptr->data>item)//左子树查找
locptr=locptr->left;
else if(item>locptr->data)//右子树查找
locptr=locptr->right;
else
{
found=true;//找到该用户
locptr->data=item;//修改密码
}
}
}

/*** 此板块是AVLTree的输出功能函数 ***/

template<typename DataType>//中序遍历函数--------------------------
inline void AVLTree<DataType>::inorder(ostream & out) const
{
inorderAux(out,myRoot);//调用中序遍历辅助函数
}

template<typename DataType>//中序遍历辅助函数(采用递归)
void AVLTree<DataType>::inorderAux(ostream & out,BinNodePointer subtreeRoot) const
{
if(subtreeRoot!=0)//平衡树非空
{
inorderAux(out,subtreeRoot->left);//遍历左子树
out<<subtreeRoot->data<<" ";//输出用户信息
inorderAux(out,subtreeRoot->right);//遍历右子树
}
}

template<typen
1361b
ame DataType>//图形输出----------------------------------
void AVLTree<DataType>::graph(ostream & out) const
{
graphAux(out,0,myRoot);//调用图形输出辅助函数
}

template<typename DataType>//图形输出辅助函数(采用递归)
void AVLTree<DataType>::graphAux(ostream & out,int indent,BinNodePointer subtreeRoot) const
{
if(subtreeRoot!=0)//平衡树非空
{
graphAux(cout,indent+8,subtreeRoot->right);//输出右子树
out<<setw(indent)<<"o"<<subtreeRoot->data<<endl;//输出叶结点'o'以及用户信息
graphAux(cout,indent+8,subtreeRoot->left);//输出左子树
}
}

//-------------------------------------------------------------------------------------
/*** 此板块主要完成AVLTree结点的插入,删除,AVLTree的平衡操作 ***/

template<typename DataType>//左旋(逆时针旋转)
void AVLTree<DataType>::L_Rotate(BinNodePointer & p)
{
BinNodePointer rc=0;
rc=p->right;//rc指向p的右子树根结点
p->right=rc->left;//rc的左子树挂接为p的右子树
rc->left=p;
p=rc;//p指向新的根结点
}

template<typename DataType>//右旋(顺时针旋转)
void AVLTree<DataType>::R_Rotate(BinNodePointer & p)
{
BinNodePointer lc=0;
lc=p->left; //lc指向p的左子树根结点
p->left=lc->right;//lc的右子树挂接为p的左子树
lc->right=p;
p=lc; //p指向新的根结点
}

template<typename DataType>//左平衡处理
void AVLTree<DataType>::leftBalance(BinNodePointer & t)
{
BinNodePointer lc=0,
rd=0;
lc=t->left;
switch(lc->bf) //LL旋转
{
case LH:
t->bf=EH;
lc->bf=EH;
R_Rotate(t);
break;

case EH: //deleteAVL需要,insertAVL用不着
t->bf=LH;
lc->bf=RH;
R_Rotate(t);
break;

case RH: //LR旋转
rd=lc->right;
switch(rd->bf)
{
case LH:
t->bf=RH;
lc->bf=EH;
break;
case EH:
t->bf=EH;
lc->bf=EH;
break;
case RH:
t->bf=EH;
lc->bf=LH;
break;
}
rd->bf=EH;
L_Rotate(t->left);//不能写L_Rotate(lc);采用的是引用参数
R_Rotate(t);
break;
}
}

template<typename DataType>//右平衡处理
void AVLTree<DataType>::rightBalance(BinNodePointer & t)
{
BinNodePointer rc=0,
ld=0;
rc=t->right;
switch(rc->bf)
{
case LH:
ld=rc->left;
switch(ld->bf)
{
case LH: //RL旋转
t->bf=EH;
rc->bf=RH;
break;
case EH:
t->bf=EH;
rc->bf=EH;
break;
case RH:
t->bf=LH;
rc->bf=EH;
break;
}
ld->bf=EH;
R_Rotate(t->right);//不能写R_Rotate(rc);采用的是引用参数
L_Rotate(t);
break;

case EH: //deleteAVL需要,insertAVL用不着
t->bf=RH;
rc->bf=LH;
L_Rotate(t);
break;

case RH: //RR旋转
t->bf=EH;
rc->bf=EH;
L_Rotate(t);
break;
}
}

template<typename DataType>//插入叶节点辅助函数
bool AVLTree<DataType>::insertAux(BinNodePointer & t, const DataType & item, bool & taller)
{
if(t==0)
{
t=new BinNode(item);//插入元素
taller=true;
}
else
{
if(item==t->data)  //树中已含该用户名,不插入(比较的是用户名)
{
taller=false;
return false;
}
else if(t->data>item)//在左子树中查找插入点(比较的是用户名)
{
if(!insertAux(t->left,item,taller))//左子树插入失败
{
return false;
}
if(taller) //左子树插入成功,且左子树增高
{
switch(t->bf)
{
case LH://原来t的左子树高于右子树
leftBalance(t);//做左平衡处理
taller=false;
break;
case EH://原来t的左子树和右子树等高
t->bf=LH;//现在左子树比右子树高
taller=true;//整棵树增高了
break;
case RH://原来t的右子树高于左子树
t->bf=EH;//现在左右子树等高
taller=false;
break;
}
}
}
else //在右子树中查找插入点
{
if(!insertAux(t->right,item,taller)) //右子树插入失败
{
return false;
}
if(taller) //右子树插入成功,且右子树增高
{
switch(t->bf)
{
case LH: //原来t的左子树高于右子树
t->bf=EH;
taller=false;
break;
case EH: //原来t的左子树和右子树等高
t->bf=RH;
taller=true;
break;
case RH: //原来t的右子树高于左子树
rightBalance(t);//做右平衡处理
taller=false;
break;
}
}
}
}
return true;//插入成功
}

template<typename DataType>//删除叶节点辅助函数
bool AVLTree<DataType>::deleteAux(BinNodePointer & t,DataType item, bool & shorter)
{
if(t==0)//不存在该元素
{
return false;//删除失败
}
else if(item==t->data)//找到元素结点(比较的是用户名)
{
BinNodePointer q=0;
if(t->left==0) //左子树为空
{
q=t;
t=t->right;
delete q;
shorter=true;
}
else if(t->right==0) //右子树为空
{
q=t;
t=t->left;
delete q;
shorter=true;
}
else //左右子树都存在
{
q=t->left;
while(q->right)
{
q=q->right;
}
t->data=q->data; //用户信息赋值(用户名,密码)
deleteAux(t->left,q->data,shorter);//在左子树中递归删除前驱结点
}
}
else if(t->data>item) //左子树中继续查找
{
if(!deleteAux(t->left,item,shorter))
{
return false;
}
if(shorter)
{
switch(t->bf)
{
case LH:
t->bf=EH;
shorter=true;
break;
case EH:
t->bf=RH;
shorter=false;
break;
case RH:
rightBalance(t); //右平衡处理
if(t->right->bf==EH)//关键之处
shorter=false;
else
shorter=true;
break;
}
}
}
else //右子树中继续查找
{
if(!deleteAux(t->right,item,shorter))
{
return false;
}
if(shorter)
{
switch(t->bf)
{
case LH:
leftBalance(t);//左平衡处理
if(t->left->bf==EH)//关键之处
shorter=false;
else
shorter=true;
break;
case EH:
t->bf=LH;
shorter=false;
break;
case RH:
t->bf=EH;
shorter=true;
break;
}
}
}
return true;
}
#endif

//---------------------------------UserInfo.h---------------------------------------
#include<iostream>
#include<fstream>
#include<string>
using namespace std;

#ifndef USERINFO
#define USERINFO

class UserInfo//定义一个UserInfo类
{
private:
string myId,
myPassword;
public:
UserInfo(){ myId="0"; myPassword="0";}//默认构造函数

UserInfo(string id,string password)//构造函数
:myId(id),myPassword(password)
{}

/*** 赋值构造函数原本是=重载,用于AVLTree类 ***/
const UserInfo & operator=(const UserInfo & rightHandSide)//赋值构造函数(deleteAux()中使用)
{
if(this!=& rightHandSide)//不是自我赋值
{
myId=rightHandSide.myId;//此语句在modify()中没有用处,在deleteAux()中有用
myPassword=rightHandSide.myPassword;
}
return *this;//返回被赋值后的*this
}
//----------------------------------------------------------------------------
/*** 此板块函数主要用于文件读写(面向文件) ***/

void writeFile()//将用户信息内容写入文件(每次只能输入一个用户信息)
{
ofstream outfile;//定义文件输出流
outfile.open("c:\\userInfoFile.txt",ios::out|ios::app|ios::binary);//打开二进制文件
if(!outfile.is_open())//文件是否可以打开
{
cerr<<"The user information file failed to open"<<endl;
exit(1);//非正常退出
}
outfile.write((char*)(this),sizeof(*this));//将用户信息写入文件
outfile.close();//关闭文件流
}

void modifyFile()//修改文件中的用户个人信息
{
fstream iofile("c:\\userInfoFile.txt",ios::in|ios::out|ios::binary);//打开二进制文件
if(!iofile.is_open())//文件是否可以打开
{
cerr<<"The user information file failed to open"<<endl;
exit(1);//非正常退出
}
int i=0;//用于文件位置定位
string str1=this->myId,//将用户原有信息先暂时保留
str2=this->myPassword;
for(;;)//读取文件数据
{
iofile.seekg(i*sizeof(*this),ios::beg);//文件流指针定位
iofile.read((char*)(this),sizeof(*this));//读出相应位置的用户信息
if(str1==this->myId) { break; }//找到要修改的用户信息时,跳出循环
if(iofile.eof()) break;//文件读取结束,跳出循环
i++;//定位值加一
}
if(str1==this->myId)//该用户名是否已找到
{
this->myPassword=str2;//修改密码
iofile.seekp(i*sizeof(*this),ios::beg);//定位到文件中将要修改的位置
iofile.write((char*)(this),sizeof(*this));//将用户信息写入
}
this->myId=str1;//this恢复到原有数据
this->myPassword=str2;
iofile.close();//关闭文件流
}

void deleteFile()//删除文件中的用户个人信息
{
fstream infile("c:\\userInfoFile.txt",ios::in|ios::binary);//打开用户信息文件
if(!infile.is_open())//文件是否可以打开
{
cerr<<"The user information file failed to open"<<endl;
exit(1);//非正常退出
}
fstream tempfile("c:\\tempFile.txt",ios::out|ios::binary|ios::trunc);//打开临时文件
if(!tempfile.is_open())
{
cerr<<"The temporary file failed to open"<<endl;
exit(1);//非正常退出
}

string str1=this->myId,//将用户原有信息先暂时保留
str2=this->myPassword;
for(;;)//读取文件数据
{
infile.read((char*)(this), sizeof(*this));//读取用户信息文件
if(infile.eof()) break;//文件是否读取结束
if(this->myId!=str1)//若不是要删除的用户信息
tempfile.write((char*)(this), sizeof(*this));//读取到临时信息文件
}
infile.close();//关闭用户信息文件
tempfile.close();//关闭临时信息文件

tempfile.open("c:\\tempFile.txt",ios::in|ios::binary);//打开临时信息文件
if(!tempfile.is_open())//临时信息文件是否可以打开
{
cerr<<"The temporary file failed to open"<<endl;
exit(1);//非正常退出
}

ofstream outfile("c:\\userInfoFile.txt",ios::out|ios::binary|ios::trunc);//打开用户信息文件
if(!outfile.is_open())//用户信息文件是否可以打开
{
cerr<<"The user information file failed to open"<<endl;
exit(1);//非正常退出
}

for(;;)
{
tempfile.read((char*)(this),sizeof(*this));//读取临时文件中的用户信息
if(tempfile.eof()) break;//临时文件是否读取结束
outfile.write((char*)(this),sizeof(*this));//重新写入到原有的用户信息文件

}
this->myId=str1;//this恢复到原有数据
this->myPassword=str2;

tempfile.close();//关闭临时信息文件流
outfile.close();//关闭用户信息文件流
}
//---------------------------------------------------------------------------------
/*** 此板块函数主要用于Menu类 ***/

string id() const { return myId; }//返回用户名

void read()//用户输入个人信息
{
cout<<"\t\t\t 1> Username :";cin>>myId;
cout<<"\t\t\t 2> Passward :";cin>>myPassword;
}

void changeId(string & id)//修改用户名
{
myId=id;
}

void change(string & password)//修改用户密码
{
myPassword=password;
}

bool compareId(string & id) const//判断用户名是否相等(未用到)
{
if(myId!=id)
return false;
return true;
}

bool comparePass(string & password) const//判断密码是否相等
{
if(myPassword!=password)
return false;
return true;
}
//-------------------------------------------------------------------------
/*** 此板块函数主要用于AVLTree类 ***/

bool operator==(const UserInfo & user) const//重载等于运算符(insertAux(),deleteAux()中使用)
{
return myId==user.myId ;//用户名比较
}

bool operator<(const UserInfo & user) const//重载小于运算符(search()中使用)(用于登录验证)
{
return myId<user.myId || myId==user.myId && myPassword<user.myPassword;//用户名,密码
}

bool operator>(const UserInfo & user) const//重载大于运算符(searchExtra()中使用)(用户名是否已注册)
{
return myId>user.myId;//用户名比较
}
//---------------------------------------------------------------------------------
/*** 此板块函数主要用于Menu类以及AVLTree类 ***/

friend istream & operator>>(istream & in,UserInfo & user)//重载输入操作运算符(Menu中可调用)
{
in>>user.myId>>user.myPassword;
return in;
}

friend ostream & operator<<(ostream & out,UserInfo & user)//重载输入操作运算符(用于Menu类中的view(),AVLTree类中graph(),inorderAux())
{
out<<"\t\t\t 1> Username : "<<user.myId<<"\t\t\t 2> Passward : "<<user.myPassword<<endl;
return out;
}
};
#endif

//-------------------------------------Menu.h------------------------------------------
#include"AVLTree.h"
#include"UserInfo.h"

#ifndef MENU
#define MENU

class Menu//定义一个Menu类
{
public:
Menu();//将文件中的数据导入到内存中,并构建AVLTree
void show();//菜单显示界面

void signUp();//注册用户名(插入)
void signIn();//登录用户名(查找)
void modify();//修改密码(修改)
void logout();//注销用户信息(删除)
void view();//查看用户信息(图形输出)
void Exit();//退出系统
private:
AVLTree<UserInfo>aTree;//定义平衡二叉树的一个对象
UserInfo user;//定义用户信息类的一个对象
};
#endif

//------------------------------------Menu.cpp---------------------------------------
#include<iostream>
using namespace std;

#include"Menu.h"

Menu::Menu()//登录界面------------------------
{
ifstream infile;//定义一个文件输入流
infile.open("c:\\userInfoFile.txt",ios::in|ios::binary);//以二进制方式打开
if(!infile.is_open())//文件是否打开
{
cerr<<"The user information file failed to open"<<endl;
exit(1);//非正常退出
}
for(;;)//将文件中的数据导入到程序中,并构建AVLTree
{
infile.read((char*)(& user),sizeof(user));//读取文件中的数据
if(infile.eof()) break;
aTree.insert(user);//将用户信息添加到AVLTree
}
infile.close();//关闭文件流
}

void Menu::show()//显示界面---------------------------
{
system("cls");//清屏
cout<<endl<<endl;//主菜单界面
cout<<"\t\t\t--------------------Welcome to User Login System--------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Sign up                                      "<<endl;
cout<<"\t\t\t                    2> Sign in                                      "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户可以根据需求做出选择
{
case 1:signUp();break;
case 2:signIn();break;
case 0:Exit();  //退出程序
default:show();break;
}
}

void Menu::signUp()//注册用户名--------------------------------
{
system("cls");//清屏
cout<<endl<<endl;//注册界面
cout<<"\t\t\t------------------------------Sign up-------------------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
string u,p,pa;
cout<<"\t\t\t 1> Username :";cin>>u;
cout<<"\t\t\t 2> Passward :";cin>>p;
cout<<"\t\t\t 3> Confirm password :";cin>>pa;//第二次输入密码,进行确认
user.changeId(u);//修改user的用户名成员
user.change(p);//修改user的密码成员
if(!user.comparePass(pa))//两次输入的密码不一致
{
system("cls");//清屏
cout<<endl<<endl;//提示错误
cout<<"\t\t\t-----------The input of the two passwords is inconsistent!----------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Sign up                                      "<<endl;
cout<<"\t\t\t                    2> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:signUp();break;
case 2:show();break;
case 0:Exit();
default:show();break;
}
}

if(!aTree.searchExtra(user))//用户名没有被注册
{
aTree.insert(user);//插入到AVLTree中
user.writeFile();//写入到文件中
system("cls");//清屏
cout<<endl<<endl;//注册成功
cout<<"\t\t\t--------------------Registered successfully!------------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Sign in                                      "<<endl;
cout<<"\t\t\t                    2> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:signIn();break;
case 2:show();break;
case 0:Exit();
default:show();break;
}
}
else//用户名已被注册
{
system("cls");//清屏
cout<<endl<<endl;//提示错误
cout<<"\t\t\t-------------------The username has been registered!----------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Sign up                                      "<<endl;
cout<<"\t\t\t                    2> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:signUp();break;
case 2:show();break;
case 0:Exit();
default:show();break;
}
}
}

void Menu::signIn()//登录用户名----------------------------------
{
system("cls");//清屏
cout<<endl<<endl;//登录界面
cout<<"\t\t\t------------------------------Sign in-------------------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
user.read();//用户输入用户名与密码
if(aTree.search(user))//在AVLTree中搜索是否有该用户名以及密码
{
system("cls");
cout<<endl<<endl;//登录界面
cout<<"\t\t\t-----------------------Log in successfully!-------------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Modify                                       "<<endl;
cout<<"\t\t\t                    2> Logout account                               "<<endl;
cout<<"\t\t\t                    3> View user information                        "<<endl;
cout<<"\t\t\t                    4> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:modify();break;
case 2:logout();break;
case 3:view();break;
case 4:show();break;
case 0:Exit();
default:show();break;
}
}
else//用户名或者密码输入错误
{
system("cls");
cout<<endl<<endl;//提示错误
cout<<"\t\t\t--------------------Username or password is error!------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Sign in                                      "<<endl;
cout<<"\t\t\t                    2> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:signIn();break;
case 2:show();break;
case 0:Exit();
default:show();break;
}
}
}

void Menu::modify()//修改密码--------------------------------
{
system("cls");
cout<<endl<<endl;//修改密码界面
cout<<"\t\t\t-----------------------Change your password-------------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
string np,cp;
cout<<"\t\t\t 1> New passward  :";cin>>np;
cout<<"\t\t\t 2> Confirm password :";cin>>cp;
if(np==cp)//两次输入的新密码一致
{
user.change(np);//修改user中的密码成员
user.modifyFile();//修改文件中的密码
aTree.modify(user);//修改AVLTree中的密码
system("cls");//清屏
cout<<endl<<endl;//密码修改成功
cout<<"\t\t\t--------------------Password modifies success!----------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Sign in                                      "<<endl;
cout<<"\t\t\t                    2> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:signIn();break;
case 2:show();break;
case 0:Exit();
default:show();break;
}
}
else//两次输入的密码不一致
{
system("cls");
cout<<endl<<endl;//提示错误
cout<<"\t\t\t-----------The input of the two passwords is inconsistent!----------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Modify                                       "<<endl;
cout<<"\t\t\t                    2> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:modify();break;
case 2:show();break;
case 0:Exit();
default:show();break;
}
}
}

void Menu::logout()//注销用户信息---------------------------------
{
system("cls");
cout<<endl<<endl;//注销用户名界面
cout<<"\t\t\t------------------------------Logout-------------------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Make sure to log out                         "<<endl;
cout<<"\t\t\t                    2> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\t\t\t Choose the number:";
int num;
cin>>num;//用户根据需求做出选择
if(num==1)//确认注销用户名
{
user.deleteFile();//删除文件中的用户名与密码
aTree.remove(user);//将AVLTree中的该用户信息(用户名与密码)移除
system("cls");
cout<<endl<<endl;//用户信息注销界面
cout<<"\t\t\t-------------------Username logout successfully!--------------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\t\t\tChoose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:show();break;
case 0:Exit();
default:show();break;
}
}
else//用户不确定注销用户信息时
{
switch(num)//用户根据需求做出选择
{
case 2:show();break;
case 3:Exit();
default:show();break;
}
}
}

void Menu::view()//查看用户信息------------------------------
{
system("cls");
cout<<endl<<endl;//管理员验证界面
cout<<"\t\t\t-------------Only administrators can view user information----------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t Verification code : ";
string password;
cin>>password;//管理员输入验证码
cout<<endl<<endl;
if(password=="201626811010")//判断验证码是否正确
{
ifstream infile;//定义文件输入流
infile.open("c:\\userInfoFile.txt",ios::in|ios::binary);//以二进制方式打开
if(!infile.is_open())
{
cerr<<"The user information file failed to open"<<endl;
exit(1);//非正常退出
}
cout<<"\t\t\t---------------The user information in the  file--------------------"<<endl;
cout<<endl;
for(;;)
{
infile.read((char*)(&user),sizeof(user));//读取文件数据
if(infile.eof()) break;
cout<<user;	//输出读取出的文件数据
}
infile.close();//关闭文件输入流
cout<<endl;
cout<<"\t\t\t-----------------------Inorder traversal----------------------------"<<endl;
cout<<endl;
aTree.inorder(cout);//验证中序遍历函数
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<endl;
aTree.graph(cout);//输出平衡二叉树的形状(逆时针旋转)
cout<<"\n\n\t\t\t Go back to sign in(Please enter 1) "<<endl;
cout<<"\n\t\t\t Go back to sign up(Please enter 2) "<<endl;
cout<<"\n\t\t\t Go back to menu(Please enter 3): ";
int num;
cin>>num;
if(num==1)//用户根据需求做出选择
{
signIn();
}
else
{
show();//主菜单界面
}
}
else//非管理员没有权限查看用户信息
{
system("cls");
cout<<endl<<endl;//提示错误
cout<<"\t\t\t-------------Sorry, you don't have permission to view --------------"<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                    1> Back to menu                                 "<<endl;
cout<<"\t\t\t                    0> Exit sysytem                                 "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t                                                                    "<<endl;
cout<<"\t\t\t--------------------------------------------------------------------"<<endl;
cout<<"\n\n\t\t\t Choose the number:";
int num;
cin>>num;
switch(num)//用户根据需求做出选择
{
case 1:show();break;
case 0:Exit();
default:show();break;
}
}
}

void Menu::Exit()//退出系统---------------------------
{
exit(0);
}

//------------------------------main.cpp--------------------------------
#include<iostream>
using namespace std;

#include"Menu.h"

int main()
{
Menu menu;//定义一个菜单类对象
menu.show();//显示用户登录界面
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: