用户登录系统(平衡树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; }
相关文章推荐
- 用户登录系统(平衡树AVLTree实现)(二)
- 物流管理系统(七)4实现用户未登录自动跳转到登录页面
- 简单java实现单用户登录系统(不是单点登录)
- zabbix3.0监控windows系统安全日志,实现监控用户登录windows并报警的功能
- 使用MVC实现用户登录注册系统—银行管理系统
- PHPwind整合最土系统用户同步登录实现方法
- ATM系统实现[1]——用户登录界面[00原创]
- Debian系统下利用vsdftpd+Mysql实现虚拟用户登录(Debian+vsftpd+Mysql)
- windows xp sp3 实现本机多用户登录系统
- qtp 订票用户登录脚本参数化实现循环播放(自带的Flight订票系统)
- SSM框架下的用户登录系统,并实现增删改
- python实现的简单用户注册登录系统
- 银行管理系统 实现用户注册 登录 存、取款 交易记录查询和修改用户信息等功能
- PHPwind整合最土系统用户同步登录实现方法
- qtp 订票用户登录脚本参数化实现循环播放(自带的Flight订票系统)
- SSM框架下的用户登录系统,并实现增删改
- JSP系统开发学习之四关于用户登录界面的补充——通过request页面传值&wel.jsp的MVC的实现
- python实现用户登录系统
- 全局不临时表实现防止用户多次登录系统
- 用户登录系统实现