前言
在步入大学的时候学的第一门面向对象的语言就是C++,一度被他的语法与设计模式所吸引,本篇博客将介绍一下博主在学习完C++基础语法的时候写的小项目,基于C++三大特性的图书管理系统,这次的小练习会对类的属性进行封装,使用继承与多态完成一个登录器登录不同的角色。
一、简单回顾C++三大特性
1.封装
在C++中类的封装完成的一个任务就是实现类的私有属性能够在外界访问 在介绍C++基础语法的时候提到使用get方法获取私有属性,使用set方法 对私有属性进行赋值。所以今天项目中依旧使用这种方法。
2.继承
本项目原理上不需要使用继承,但是为了实现多态,就使用上了继承.继承有 助于我们对类进行扩展,更是实现多态的一个必要条件。
3.多态
顾名思义,就是一段代码实现不同的展示效果,通过基类的指针指向子类的对象 调用被重写的重名函数,实现多种表现。
二、实现一个登录器将输入的密码隐层起来
1.前置知识
① getch() 无回显键入
实现登录器首先要将输入的数据隐藏起来,然后再考虑使用*替换 getch这个函数是一个不回显函数,当用户按下某个字符时,函数 自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏 但是这个函数并非标准函数,要注意移植性!
② \b 退格
是ASCII表中的一个转义字符代表回退一格 我们使用 \b空格\b 达到将想要删除的字符进行覆盖 解释一下 \b空格 覆盖的是原来的一个字符 后面那个\b是将新键入的 backspace 字符覆盖掉
2.效果展示
① 密码加密
② 登录成功
③ 登录失败
3.实现方法
注意点都在代码的注释中 • 1
代码如下:
# include<iostream> using namespace std; # include<conio.h> int main() { char passward[20]; int i = 0, j, k; char ch = '0'; cout << "请输入您的密码:"; j = 0; k = 1; i = 0; memset(passward, '\0', sizeof(passward)); while (1) { ch = _getch();//最后输入回车没有将回车存入密码中,而是将他给吃掉了; if (ch == 13) {//13在ASCII表中代表回车 break; } else { if (ch != 8) {//代表键入删除键 if (i < 19) {//如果输入次数大于19就不再将从键盘读取的字符存进数组; passward[i] = ch; } cout << "*"; } else {//其余任何键都将以*的形式打印 if (i == 0) {//如果没有键入就删除是不行的,需要加以限定让i回到0; ch = '\0'; i--; } else { cout << "\b \b"; passward[i - 1] = '\0'; ch = '\0'; i = i - 2; } } } i++; } cout << endl; cout << "passward is : 123123" <<endl; cout << "you put is " << passward << endl; if (strcmp(passward, "123123") == 0) { cout << "密码正确" << endl; } else { cout << "密码错误" << endl; } cout << endl; return 0; }
三、程序运行截图
1.主题设置
2.主菜单
3.用户操作界面
4.管理员操作界面
5.登录注册界面
用户与管理员公用,实现多态
6.查阅图书
这里图书的主键是书名与作者,只有书名与作者相同时才会触发查重机制 查重机制会在新增图书时触发自动合并。
四、项目中包含的类及其作用
这里只讲函数的声明,具体的实现在源代码中 • 1
1.信息节点类
博主当时为了偷懒管理员与用户信息设置的是一个类作为节点,大家可以多实现几个类 添加几个不同的属性,节点类主要包含节点类与属性类,用于存储信息,组成链表。
class UaAdate {//------------------用户与管理员的资料----------------------------- private: string id; string passward; string secproblem; string secanswer; UaAdate* next; public: UaAdate() { } UaAdate(string ID, string Passward, string Secproblem, string Secanswer) { id = ID; passward = Passward; secproblem = Secproblem; secanswer = Secanswer; } void setpassward(string passward) {//--------------------------------------------设置密码 this->passward = passward; } void setnext(string id, string passward, string secproblem, string secanswer) {//设置下一节点 next= new UaAdate(id,passward,secproblem,secanswer); next->next = NULL; } string getid() {//-----------------------------------------------------------------获取id return this->id; } string getpassward() {//-----------------------------------------------------------获取密码 return this->passward; } string getsecproblem() {//--------------------------------------------------------获取密保问题 return this->secproblem; } string getsecanswer() {//---------------------------------------------------------获取密保答案 return this->secanswer; } UaAdate*& getnext() {//------------------------------------------------------------节点的指针域 return next; } };
2.链表基类
链表基类的作用就是实现基类的指针指向子类的对象,实现多态 主要的功能是对链表的增删改查。
class baselink {//----------------------节点功能类----------------------- public: virtual void addnode(string id, string passward, string secproblem, string secanswer)=0; virtual UaAdate* looklink(string id) = 0; virtual void savelink() = 0; virtual void printlink() = 0; virtual void delnode(string id) = 0; };
3.用户链表类
这里的用户类头结点使用的UaAdate,大家可以多实现几个数据类型,将用户数据类型设置的 与管理员类型不一样。主要对链表基类中的接口进行实现
class Userlink :public baselink{//-----------------用户继承---------------------------- private: UaAdate* Userhead; public: //---------------------------------------------------从用户文件中获取信息 Userlink() { } //------------------------------------------查找函数(给id查节点) UaAdate* looklink(string id) { } //---------------------------------------------删除某一节点 void delnode(string id) { } //在末尾加上一个新的节点 void addnode(string id, string passward, string secproblem, string secanswer) { } void printlink() {//----------------------------------------打印链表 };
4.管理员链表类
与用户链表类很相似
class Admlink :public baselink { private: UaAdate* Admhead; public: //------------------------------------------从文件中获取管理员信息 Admlink() { } UaAdate* looklink(string id) {//查找函数 } void savelink() { } void printlink() { } void addnode(string id, string passward, string secproblem, string secanswer) { } //---------------------------------------------删除某一节点} void delnode(string id) { };
5.图书节点类
对图书信息进行封装,用于组成链表中的节点
class bookdate {//--------------------------------------------------书类 private: string name; string writer; int sum; string bookclass; bookdate* next; public: bookdate() { } bookdate(string name,string writer,int sum,string bookclass){ this->name = name; this->writer = writer; this->sum = sum; this->bookclass = bookclass; } void setnext(string name,string writer,int sum,string bookclass) { this->next = new bookdate(name,writer,sum,bookclass); this->next->next = NULL; } void setsum(int sum) { this->sum = sum; } void setbookclass(string bookclass) { this->bookclass = bookclass; } bookdate*& getnext() { return next; } string getname() { return name; } string getwriter() { return writer; } int getsum() { return sum; } string getbookclass() { return bookclass; } };
6.图书链表类
对图书的增删改查
class booklink {//-----------------------------------------------书库存书的功能类 private: bookdate* head; public: booklink() {//------------------------------------------初始化私有成员 } bookdate*& gethead() { return head; } bookdate* looklink(string name, string writer) {//--------------查重--------- } void savelink() {//--------------------------------------------------将新链表储存一下 } void creatnode(string name,string writer,int sum,string bookclass) {//----------增书 } void selectbook(string name,string writer) {//--------------------------查书 } void rebuildbook(string name,string writer,int sum,string bookclass) {//-改书 } void printlink() {//-----------------------------------------------打印链表 } };
7.用户借记节点类
用户借书的时候,记录一下借阅的图书的数量,借书人的基本信息 并对类中的信息进行封装,作为借记功能类的节点使用
class userbook {//------------------------------------------------用户借书登记信息 private: string bookname; string bookwriter; int sum; string name; string phone; userbook* next; public: userbook() { next = NULL; } userbook(string bookname, string bookwriter, int sum, string name, string phone) { this->bookname = bookname; this->bookwriter = bookwriter; this->sum = sum; this->name=name; this->phone = phone; this->next = NULL; } void setnext(string bookname,string bookwriter,int sum,string name,string phone) { this->next = new userbook(bookname,bookwriter, sum, name, phone); } void setsum(int sum) { this->sum = sum; } userbook*& getnext() { return next; } string getbookname() { return bookname; } string getbookwriter() { return bookwriter; } int getbooksum() { return sum; } string getusername() { return name; } string getuserphone() { return phone; } };
8.用户借记链表类
用户借书的信息进行记录
class userbooklink {//-----------------------------------------------用户借书登记功能类 private: userbook* head; public: userbooklink() {//-------------------------------------------------构造函数将文件里面的东西读出来 } userbook* looklink(string bookname,string bookwriter,string name) {//有就返回,没有就返回空 } void addonenode(string bookname, string bookwriter, int sum, string name, string phone) { } void savelink() {//--------------------------------存链表 } void changesum(string bookname,string bookwriter,int sum,string name) {//修改书的数量 };
9.多态的实现
这里实现多态主要在登录器处进行了实现,使用的一个登录器可以进行两种身份的登入。
int main() { baselink* p; Userlink U1; Admlink A1; booklink b; p = &A1; char n;bool k; mainHere: system("cls"); mainMenu(); n = Shield_4(); if (n == '1' || n == '2') { if (n == '1') { p = &U1; } else if (n == '2') { p = &A1; string Admpassward; system("cls"); cout << "请输入管理员密匙:"; cin >> Admpassward; if (Admpassward != "芝麻开门") { cout << "密匙不匹配,您应该不是管理员"; system("pause"); goto mainHere; } } k=thisMenu(p);//登录菜单 if (k == false) { goto mainHere; } else { if (p == &A1) { k=Admmeun(); } else if (p == &U1) { k=Usermeun(); } } if (k == false) { goto mainHere; } } else if (n == '3') { setColor(); goto mainHere; } else if (n == '4') { exit(0); } return 0; }
10.其余全局增删改查函数
其余的全局增删改查函数均是定义以上类的对象 然后根据需求,书写一些提示性语句,实现一定的用户体验。
五、源代码及项目及项目结构
项目结构
这里有4个文件,作用体现在了文件名上。
程序模式图
源代码
#include<iostream> #include<fstream> #include<windows.h> #include<cstring> #include<conio.h> using namespace std; class baselink; bool regkey(baselink* p);//注册 bool landkey(baselink* p, char n);//登录,修改密码,注销账户; bool lookpassward(baselink* p);//找回密码 class UaAdate {//------------------用户与管理员的资料----------------------------- private: string id; string passward; string secproblem; string secanswer; UaAdate* next; public: UaAdate() { } UaAdate(string ID, string Passward, string Secproblem, string Secanswer) { id = ID; passward = Passward; secproblem = Secproblem; secanswer = Secanswer; } void setpassward(string passward) {//--------------------------------------------设置密码 this->passward = passward; } void setnext(string id, string passward, string secproblem, string secanswer) {//设置下一节点 next= new UaAdate(id,passward,secproblem,secanswer); next->next = NULL; } string getid() {//-----------------------------------------------------------------获取id return this->id; } string getpassward() {//-----------------------------------------------------------获取密码 return this->passward; } string getsecproblem() {//--------------------------------------------------------获取密保问题 return this->secproblem; } string getsecanswer() {//---------------------------------------------------------获取密保答案 return this->secanswer; } UaAdate*& getnext() {//------------------------------------------------------------节点的指针域 return next; } }; class baselink {//----------------------节点功能类----------------------- public: virtual void addnode(string id, string passward, string secproblem, string secanswer)=0; virtual UaAdate* looklink(string id) = 0; virtual void savelink() = 0; virtual void printlink() = 0; virtual void delnode(string id) = 0; }; class Userlink :public baselink{//-----------------用户继承---------------------------- private: UaAdate* Userhead; public: Userlink() {//---------------------------------------------------从用户文件中获取信息 Userhead = new UaAdate; ifstream infile; string id; string passward; string secproblem; string secanswer; UaAdate* p=Userhead,*q=NULL;//头节点不存东西 infile.open("用户信息"); while ( infile >> id >> passward >> secproblem >> secanswer) { p->setnext(id, passward, secproblem, secanswer); p = p->getnext(); } infile.close(); } UaAdate* looklink(string id) {//------------------------------------------查找函数(给id查节点) int k = 1; UaAdate* p = Userhead; while (p->getnext() != NULL) { p = p->getnext(); if (id == p->getid()) { k = 0; break; } } if (k == 0) { return p; } else { return NULL; } } void delnode(string id) {//---------------------------------------------删除某一节点 UaAdate* p,*q=NULL,*t=NULL,*r=NULL; p = Userhead; while (p->getnext() != NULL) { p = p->getnext(); cout << p->getid()<<endl; if (p->getnext()->getid()==id) { if (p->getnext()->getnext() == NULL) { q = p->getnext(); p->getnext() = NULL; delete q; } else { p->getnext() = p->getnext()->getnext(); break; } } } } void addnode(string id, string passward, string secproblem, string secanswer) {//在末尾加上一个新的节点 UaAdate* p; p = Userhead; while (p->getnext() != NULL) { p = p->getnext(); } p->setnext(id, passward, secproblem, secanswer); } void savelink() {//----------------------------------------将新链表储存一下 ofstream outfile; outfile.open("用户信息"); UaAdate* p; p = Userhead; while (p->getnext() != NULL) { p = p->getnext(); outfile << p->getid() << " "<<p->getpassward()<<" "<<p->getsecproblem()<<" "<<p->getsecanswer()<<endl; } outfile.close(); } void printlink() {//----------------------------------------打印链表 UaAdate* p; p = Userhead; while (p->getnext() != NULL) { p = p->getnext(); cout << p->getid() << " " << p->getpassward() << " " << p->getsecproblem() << " " << p->getsecanswer() << endl; } } }; class Admlink :public baselink {//-----------------管理员继承---------------------------- private: UaAdate* Admhead; public: Admlink() {//------------------------------------------从文件中获取管理员信息 Admhead = new UaAdate; ifstream infile; string id; string passward; string secproblem; string secanswer; UaAdate* p = Admhead;//头节点不存东西 infile.open("管理员信息"); while (infile >> id >> passward >> secproblem >> secanswer) { p->setnext(id, passward, secproblem, secanswer); p = p->getnext(); } } UaAdate* looklink(string id) {//查找函数 int k = 1; UaAdate* p = Admhead->getnext(); while (p->getnext() != NULL) { p = p->getnext(); if (id == p->getid()) { k = 0; break; } } if (k == 0) { return p; } else { return NULL; } } void savelink() { ofstream outfile; outfile.open("管理员信息"); UaAdate* p; p = Admhead; while (p->getnext() != NULL) { p = p->getnext(); outfile << p->getid() << " " << p->getpassward() << " " << p->getsecproblem() << " " << p->getsecanswer() << endl; } outfile.close(); } void printlink() { UaAdate* p; p = Admhead; while (p->getnext() != NULL) { p = p->getnext(); cout << p->getid() << " " << p->getpassward() << " " << p->getsecproblem() << " " << p->getsecanswer() << endl; } } void addnode(string id, string passward, string secproblem, string secanswer) { UaAdate* p; p = Admhead; while (p->getnext() != NULL) { p = p->getnext(); } p->setnext(id, passward, secproblem, secanswer); } void delnode(string id) {//---------------------------------------------删除某一节点 UaAdate* p, * q = NULL; p =Admhead; while (p->getnext() != NULL) { p = p->getnext(); cout << p->getid() << endl; if (p->getnext()->getid() == id) { if (p->getnext()->getnext() == NULL) { q = p->getnext(); p->getnext() = NULL; delete q; } else { p->getnext() = p->getnext()->getnext(); break; } } } } }; class bookdate {//--------------------------------------------------书类 private: string name; string writer; int sum; string bookclass; bookdate* next; public: bookdate() { } bookdate(string name,string writer,int sum,string bookclass){ this->name = name; this->writer = writer; this->sum = sum; this->bookclass = bookclass; } void setnext(string name,string writer,int sum,string bookclass) { this->next = new bookdate(name,writer,sum,bookclass); this->next->next = NULL; } void setsum(int sum) { this->sum = sum; } void setbookclass(string bookclass) { this->bookclass = bookclass; } bookdate*& getnext() { return next; } string getname() { return name; } string getwriter() { return writer; } int getsum() { return sum; } string getbookclass() { return bookclass; } }; class booklink {//-----------------------------------------------书库存书的功能类 private: bookdate* head; public: booklink() {//------------------------------------------初始化私有成员 head = new bookdate; head->getnext() = NULL; string name; string writer; int sum; string bookclass; ifstream infile; bookdate* p;; p = head; infile.open("图书信息"); while (infile >> name >> writer >> sum >> bookclass) { p->setnext(name, writer, sum, bookclass); p = p->getnext(); p->getnext() = NULL; } } bookdate*& gethead() { return head; } bookdate* looklink(string name, string writer) {//--------------查重--------- bookdate* p; int k = 0; p = head; while (p->getnext() != NULL) { p = p->getnext(); if (p->getname() == name && p->getwriter() == writer) { k = 1; return p; break; } } if (k == 0) { return NULL; } } void savelink() {//--------------------------------------------------将新链表储存一下 bookdate* p; p = head; ofstream outfile; outfile.open("图书信息"); while (p->getnext()!=NULL) { p = p->getnext(); outfile << p->getname() << " " << p->getwriter() << " " << p->getsum() << " " << p->getbookclass() << endl; } outfile.close(); } void creatnode(string name,string writer,int sum,string bookclass) {//----------增书 bookdate* p;int k = 0; ifstream infile; p = head; while (p->getnext() != NULL) { p = p->getnext(); if (p->getname() == name && p->getwriter() == writer) { p->setsum(sum + p->getsum());//书库中原来就有的话就将原来数量与现在的相加 k = 1; break; } } if (k == 0) {//书库中没有的话就加在链表末尾 p->setnext(name, writer, sum, bookclass); savelink(); } else { savelink(); } } void delonenode(string name,string writer) {//----------------------删除某一本书 bookdate* p,*q=NULL;//记得测试尾节点 p = head; while (p->getnext() != NULL) { if (p->getnext()->getname() == name && p->getnext()->getwriter() == writer) { if (p->getnext()->getnext() == NULL) { q = p->getnext(); p->getnext() = NULL; delete q; break; } else { q = p->getnext(); p->getnext() = p->getnext()->getnext(); delete q; break; } } p = p->getnext(); } savelink(); } void selectbook(string name,string writer) {//--------------------------查书 bookdate* p; p = head; while (p->getnext() != NULL) { p = p->getnext(); if (p->getname() == name && p->getwriter() == writer) { cout << "您找的图书信息如下:" << endl; cout << "书名" << "\t" << "作者" << "\t" << "数量" << "\t" << "类别" << endl; cout << p->getname() << "\t" << p->getwriter() << "\t" << p->getsum() << "\t" << p->getbookclass(); break; } } } void rebuildbook(string name,string writer,int sum,string bookclass) {//-改书 bookdate* p; p = head; while (p->getnext() != NULL) { p = p->getnext(); if (p->getname() == name && p->getwriter() == writer) { p->setsum(sum); p->setbookclass(bookclass); break; } } savelink(); } void printlink() {//-----------------------------------------------打印链表 bookdate* p; p = head; while (p->getnext() != NULL) { p = p->getnext(); cout << p->getname() << " " << p->getwriter() <<" "<<p->getsum()<<" "<<p->getbookclass()<< endl; } } }; class userbook {//------------------------------------------------用户借书登记信息 private: string bookname; string bookwriter; int sum; string name; string phone; userbook* next; public: userbook() { next = NULL; } userbook(string bookname, string bookwriter, int sum, string name, string phone) { this->bookname = bookname; this->bookwriter = bookwriter; this->sum = sum; this->name=name; this->phone = phone; this->next = NULL; } void setnext(string bookname,string bookwriter,int sum,string name,string phone) { this->next = new userbook(bookname,bookwriter, sum, name, phone); } void setsum(int sum) { this->sum = sum; } userbook*& getnext() { return next; } string getbookname() { return bookname; } string getbookwriter() { return bookwriter; } int getbooksum() { return sum; } string getusername() { return name; } string getuserphone() { return phone; } }; class userbooklink {//-----------------------------------------------用户借书登记功能类 private: userbook* head; public: userbooklink() {//-------------------------------------------------构造函数将文件里面的东西读出来 string bookname; string bookwriter; int sum=0; string name; string phone; head = new userbook; userbook* p=head; ifstream infile; infile.open("用户借书信息"); while (infile >> bookname >> bookwriter >> sum >> name >> phone) { p->setnext(bookname, bookwriter, sum, name, phone); p = p->getnext(); } infile.close(); } userbook* looklink(string bookname,string bookwriter,string name) {//有就返回,没有就返回空 userbook* p = head;int k = 0; //可以用来查重 while (p->getnext() != NULL) { p = p->getnext(); if (p->getbookname() == bookname && p->getbookwriter() == bookwriter && p->getusername() == name) { k = 1; return p; } } if (k == 0) { return NULL; } } void addonenode(string bookname, string bookwriter, int sum, string name, string phone) { userbook* p = head; while (p->getnext() != NULL) { p = p->getnext(); } p->setnext(bookname, bookwriter, sum, name, phone); savelink(); } void savelink() {//--------------------------------存链表 userbook* p; p = head; ofstream outfile; outfile.open("用户借书信息"); while (p->getnext() != NULL) { p = p->getnext(); outfile << p->getbookname() << " " << p->getbookwriter() << " " << p->getbooksum() << " " << p->getusername() <<" "<<p->getuserphone()<< endl; } outfile.close(); } void changesum(string bookname,string bookwriter,int sum,string name) {//修改书的数量 userbook* p = head; while (p->getnext() != NULL) { p = p->getnext(); if (p->getbookname() == bookname && p->getbookwriter() == bookwriter && p->getusername() == name) { p->setsum(sum); break; } } savelink(); } }; //-------------------------------------全局函数区---------------------------------- //用户与管理员 bool landkey(baselink* p, char n) {//登录,修改密码,注销账户,均需要输入密码,所以公用登陆器函数,以n的不同加以区分; UaAdate * f = NULL;//用户与管理员的登陆器//1登录 4改密码 5注销 string id; char passward[20]; string secproblem; string secanswer; int i = 0, j, k; char ch = '0'; cout << "请输入您的ID:"; j = 0;k = 1; IDD: Here1: id = "\0"; cin >> id; if (id.length() > 10) { if (j > 2) { system("cls");cout << "您多次操作失误,将要返回主菜单"; return false; } cout << "您输入的ID不合规范,请重新输入:"; j++; goto Here1; } f = p->looklink(id); if (f == NULL) { cout << "您输入的id不存在,请重新输入:"; if (k == 4) { system("cls");cout << "您多次操作失误,将要返回主菜单"; return false; } k++; goto IDD; } cout << "请输入您的密码:"; j = 0;k = 1; PassWard: Here2: i = 0; memset(passward, '\0', sizeof(passward)); while (1) { ch = _getch();//最后输入回车没有将回车存入密码中,而是将他给吃掉了; if (ch == 13) { break; } else { if (ch != 8) { if (i < 19) {//如果输入次数大于19就不再将从键盘读取的字符存进数组; passward[i] = ch; } cout << "*"; } else { if (i == 0) { ch = '\0'; i--; } else { cout << "\b \b"; passward[i - 1] = '\0'; ch = '\0'; i = i - 2; } } } i++; } cout << endl; if (strlen(passward)> 19) {//当检测到密码有19个长度时就清理密码串,重新输入; cout << "您的密码不合规范,请重新输入:";//当小于等于18个长度时将跳过这个步骤; j++; if (j > 2) { system("cls");cout << "您多次操作失误,将要返回主菜单"; return false;//密码输入不合规范三次 } goto Here2; } if (passward!=f->getpassward()) { cout << "密码错误,请重新输入:"; if (k == 4) { system("cls");cout << "您多次密码输入错误,将要返回主菜单" << endl; system("pause"); return false; } k++; goto PassWard; } else { if (n == '1') { system("cls"); cout << "登录成功!" << endl; system("date/t"); system("time/t"); return true; } else if (n == '4') { cout << "为了您的账户安全,请输入您的密保!" << endl; cout << "您的密保问题是:" << f->getsecproblem() << endl; cin >> secanswer; if (secanswer == f->getsecanswer()) { cout << "请输入您新的密码:"; string newpassward; cin >> newpassward; f->setpassward(newpassward); p->savelink(); system("cls"); cout << "密码修改成功!"; return true; } else { system("cls"); cout << "您的证据不充分,修改失败!"; return false; } } else if (n == '5') { cout << "您的密保问题是:" << f->getsecproblem() << endl; cout << "请输入您的密保答案:"; cin >> secanswer; if (secanswer == f->getsecanswer()) { char t; cout << "您确定要将账号注销吗?" << endl << "1.确认 2.我再犹豫一下" << endl << "please you chose"; while (1) { t = _getch();if (t == '1' || t == '2')break; } if (t == '1') { p->delnode(id); p->savelink(); system("cls"); cout << endl << "注销账号成功!"; return true; } else if (t == '2') { system("cls"); cout << endl << "您放弃了注销账号想要返回主菜单"; return false; } } else { cout << "您的密保输入错误,注销账户失败!"; return false; } } } } //注册账号 bool regkey(baselink* p) {//用户与管理员的注册器 UaAdate* f = NULL; string id; string passward; string secproblem; string secanswer; int j = 0, k = 1; cout << "请您输入您的ID这将这将作为您登陆的账号:"; IDD: Here1: cin >> id; if (id.length() > 10) { cout << "您输入的ID不合规范,请重新输入:"; if (j == 3) { cout << endl << "您多次操作失误,即将返回上一层" << endl;system("pause"); return false; } j++; goto Here1; } else { f = p->looklink(id); if (f != NULL) { cout << "此id已存在,请重新输入!"; if (k == 3) { cout << endl << "您多次操作失误,即将返回上一层" << endl;system("pause"); return false; } k++; goto IDD; } } cout << "请输入您的密码:"; Here2: cin >> passward; if (passward.length() > 18) { cout << "您输入的密码不合规范,请重新输入:"; goto Here2; } cout << "设置您的密保(这将是您找回密码的重要依据):"; cin >> secproblem; cout << "请输入您密保的答案:"; cin >> secanswer; p->addnode(id, passward, secproblem, secanswer);//注册; p->savelink(); cout << "注册成功!"; return true; } //找回密码 bool lookpassward(baselink* p) {//找回密码,不需要输入密码 UaAdate * f = NULL; string id; string passward;; string secproblem; string secanswer; int i = 0, j, k; char ch = '0'; cout << "请输入您的ID:"; j = 0;k = 1; IDD: Here1: id = "\0"; cin >> id; if (id.length() > 10) { if (j > 2) { cout << endl << "您多次操作失误,即将返回上一层" << endl;system("pause"); return false; } cout << "您输入的ID不合规范,请重新输入:"; j++; goto Here1; } f = p->looklink(id); if (f == NULL) { cout << "您输入的id不存在,请重新输入:"; if (k == 4) { cout << endl << "您多次操作失误,即将返回上一层" << endl;system("pause"); return false; } k++; goto IDD; } cout << "您的密保问题是:" << f->getsecproblem() << endl;; cout << "请输入您密保问题的答案:"; cin >> secanswer; if (secanswer == f->getsecanswer()) { cout << "您的证据充分,您的账户信息如下:" << endl << "ID:" << f->getid() << endl << "密码:" << f->getpassward(); return true; } else { cout << "您提供的证据不充分,密码找回失败"; return false; } } //对书进行操作的函数 void addbook() { booklink B; string name; string writer; string bookclass; int sum,i=0; cout << "请输入图书的名称:"; cin >> name; cout << "请输入图书作者:"; cin >> writer; cout << "请输入您要存的本数:"; while (i < 3) { cin >> sum; if (sum <= 0) { cout << "您输入的数量不合法请重新输入:"; sum = 0; i++; if (i == 2) { cout << "您多次输入不合法,即将返回上一层" << endl; system("pause"); return; } } else break; } i = 0; cout << "请输入您要存的书的种类(科学,文学,青春,爱情,恐怖):"<<endl; while (i < 3) { cin >> bookclass; if (bookclass == "科学" || bookclass == "文学" || bookclass == "青春" || bookclass == "爱情" || bookclass == "恐怖") { break; } else { cout << "您输入的种类不合法请重新输入:"; i++; if (i == 2) { cout << "您多次输入错误,即将返回上一层" << endl; system("pause"); return; } } } cout << "您确定要将此图书存入书库吗?" << endl; cout << "1.确认无误 2.我不想存了" << endl; cout << "please your choose:"; char n='0'; while (1) { n = _getch(); if (n == '1' || n == '2') { break; } } if (n == '1') { B.creatnode( name,writer,sum,bookclass); } else { return; } } void delbook() {//-----------------------删除某一本书 booklink B; bookdate *p = NULL; string name; string writer; int i = 0; cout << "请输入您要下架的书名:"; cin >> name; cout << "请输入您要下架图书的作者"; cin >> writer; p=B.looklink(name, writer); if (p == NULL) { cout << "您所查找的书不在书库内,不需要下架!" << endl << "返回上一层";system("pause"); return; } else { cout << "检测到书库中确实有此书信息如下:"<<endl; cout << "书名" << "\t" << "作者" << "\t" << "数量" << "\t" << "类别" << endl; cout << p->getname()<<"\t" << p->getwriter()<<"\t" << p->getsum()<<"\t" << p->getbookclass()<<endl; cout << "您确认删除该图书信息吗?"; cout << "1.确认无误 2.我不想删除这本"; char n = '0'; while (1) { n = _getch(); if (n == '1' || n == '2') { break; } } if (n == '1') { B.delonenode(name, writer); } else if (n == '2') { cout << "您放弃了删除书本,返回上一层" << endl; system("pause"); } } } void selectbook(){//---------------------查找某一本书------书名-------类别-------作者 booklink B; string name; string writer; string bookclass; int sum, i = 0;char n = '0'; bookdate* p = NULL; p = B.gethead(); cout<<endl << "1.按书名" << endl << "2.按作者" << endl << "3.按类别" << endl; while (1) { n = _getch(); if (n == '1' || n == '2' || n == '3') { break; } } if (n == '1') { cout << "请输入您要查找的书名:"; cin >> name; cout << "您要查找的结果如下(如果列表为空,则没有查到您要找的书):" << endl; cout << "书名" << "\t" << "作者" << "\t" << "数量" << "\t" << "类别" << endl; while (p->getnext() != NULL) { p = p->getnext(); if(p->getname()==name) cout << p->getname() << "\t" << p->getwriter() << "\t" << p->getsum() << "\t" << p->getbookclass() << endl; } } else if (n == '2') { cout << "请输入您要查找的作者"; cin >> writer; cout << "您要查找的结果如下(如果列表为空,则没有查到您要找的书):" << endl; cout << "书名" << "\t" << "作者" << "\t" << "数量" << "\t" << "类别" << endl; while (p->getnext() != NULL) { p = p->getnext(); if (p->getwriter()==writer) cout << p->getname() << "\t" << p->getwriter() << "\t" << p->getsum() << "\t" << p->getbookclass() << endl; } } else if (n == '3') { cout << "请输入您要查找的书的类型:"; while (i < 3) { cin >> bookclass; if (bookclass == "科学" || bookclass == "文学" || bookclass == "青春" || bookclass == "爱情" || bookclass == "恐怖") break; else { cout << "你输入的种类不合法,请重新输入:"; i++; if (i == 2) { cout << "您多次输入不合法,即将返回主菜单" << endl; system("pause"); return; } } } cout << "您要查找该类书的结果如下(如果列表为空,则没有查到您要找的书):" << endl; cout << "书名" << "\t" << "作者" << "\t" << "数量" << endl; while (p->getnext() != NULL) { p = p->getnext(); if (p->getbookclass()==bookclass) cout << p->getname() << "\t" << p->getwriter() << "\t" << p->getsum()<< endl; } } } void rebuildbook() {//-------------------修改某一本书 booklink B; string name; string writer; string bookclass; int sum, i = 0; bookdate* p; char n; //p = B.gethead(); cout << "请输入您要修改的书名:"; cin >> name; cout << "请输入您要修改书的作者:"; cin >> writer; p = B.looklink(name,writer); if (p == NULL) { cout << "书库中没有找到该书,即将返回主菜单" << endl;system("pause");return; } else { system("cls"); cout << "书库中找到了您所要修改的书,信息如下:"<<endl; cout << "书名" << "\t" << "作者" << "\t" << "数量" << "\t" << "类别" << endl; cout << p->getname() << "\t" << p->getwriter() << "\t" << p->getsum() << "\t" << p->getbookclass() << endl; cout << "请输入您要修改的类型:" << endl; cout << "1.数量 2.类型"; while (1) { n = _getch(); if (n == '1' || n == '2') { break; } } if (n == '1') { i = 0; cout<<endl << "请输入新的图书数量:"; while (i < 3) { cin >> sum; if (sum > 0) { break; } else { cout << "您输入的数量不合法请重新输入:"; i++; sum = 0; if (i == 2) { cout << "您多次操作失误,将要返回主菜单" << endl; system("pause"); return; } } } B.rebuildbook(p->getname(), p->getwriter(), sum, p->getbookclass()); cout << "修改成功,即将返回主菜单" << endl; system("pause"); return; } else if (n == '2') { i = 0; cout<<endl << "请输入新的图书类别:"; while (i < 3) { cin >> bookclass; if (bookclass == "科学" || bookclass == "文学" || bookclass == "青春" || bookclass == "爱情" || bookclass == "恐怖") break; else { cout << "您输入的类别不合法,请重新输入:"; i++; if (i == 2) { cout << "您多次操作失误,即将返回主菜单!"; system("pause"); return; } } } B.rebuildbook(p->getname(),p->getwriter(),p->getsum(),bookclass); cout << "更改成功,即将返回主菜单!" << endl; system("pause"); return; } } } void sortbook() { booklink B; bookdate* p,*q,t; p = B.gethead(); for (p=p->getnext();p->getnext() != NULL;p = p->getnext()) { for (q = p->getnext();q != NULL;q = q->getnext()) { if (p->getsum() < q->getsum()) { t = *p; *p = *q; *q = t; t.getnext() = p->getnext(); p->getnext() = q->getnext(); q->getnext() = t.getnext(); } } } p = B.gethead(); cout << "书库中书的信息如下:" << endl; cout << "名称" << "\t" << "作者" << "\t" << "数目" << "\t" << "书的类别" << endl; while (p->getnext() != NULL) { p = p->getnext(); cout << p->getname() << "\t" << p->getwriter() << "\t" << p->getsum() << "\t" << p->getbookclass()<<endl; } } void userlendbook() {//---------------------------------------------------用户借书 booklink B; bookdate *Bp = NULL; userbooklink U; userbook *Up = NULL; string bookname; string bookwriter; int sum = 0; string name; string phone;int i = 0; cout << "请输入您想要借阅的图书名:"; cin >> bookname; cout << "请输入您想借阅的图书作者:"; cin >> bookwriter; cout << "请输入您的姓名:"; cin >> name; Bp=B.looklink(bookname,bookwriter); Up = U.looklink(bookname,bookwriter,name); if (Bp == NULL||Up!=NULL&&Up->getbooksum()>0) { if (Bp == NULL) { cout << "书库中没有找到您要借的书,即将返回上一层" << endl; system("pause"); system("cls"); } else if (Up != NULL&&Up->getbooksum()>0) { cout << "您之前借过该书但没有还,请您还了之后再来借书,即将返回上一层" << endl; system("pause"); system("cls"); } return; } else if (Bp != NULL && Up != NULL && Up->getbooksum() == 0) { cout << "系统检测到您之前借过书,但已归还,请输入您再借的本数:"; while (i < 3) { cin >> sum; if (sum > 0 && sum <= Bp->getsum()) { break; } else { cout << "您输入的数量不合法,请重新输入:"; i++; sum = 0; if (i == 2) { cout << "您操作失误次数太多,即将返回主菜单" << endl; system("pause"); return; } } } B.rebuildbook(Bp->getname(), Bp->getwriter(), Bp->getsum() - sum, Bp->getbookclass()); Up->setsum(sum); U.savelink(); cout << "借书成功!" << endl; system("pause"); system("cls"); } else { cout << "书库中找到了您所要借阅的书,信息如下:" << endl; cout << "书名" << "\t" << "作者" << "\t" << "数量" << "\t" << "类别" << endl; cout << Bp->getname() << "\t" << Bp->getwriter() << "\t" << Bp->getsum() << "\t" << Bp->getbookclass() << endl; cout << "请输入您要借阅的数量:"; while (i < 3) { cin >> sum; if (sum > 0&&sum<=Bp->getsum()) { break; } else { cout << "您输入的数量不合法,请重新输入:"; i++; sum = 0; if (i == 2) { cout << "您操作失误次数太多,即将返回主菜单" << endl; system("pause"); return; } } } cout << "为了便于联系,请您留下电话号码:"; cin >> phone; cout << "您确定要借阅" << Bp->getname() << "书" << sum << "本吗?" << endl; cout << "1.确定借阅 2.我再犹豫一下" << endl; char n = '0'; while (1) { n = _getch(); if (n == '1' || n == '2') { break; } } if (n == '1') {//-------------------------------------------------------------- B.rebuildbook(Bp->getname(),Bp->getwriter(), Bp->getsum()-sum, Bp->getbookclass()); U.addonenode(bookname, bookwriter, sum, name, phone); cout << "借书成功!" << endl; system("pause"); system("cls"); return; } else { cout << "您放弃了借书,即将返回主菜单" << endl; system("pause"); system("cls"); return; } } } void brobook() {//---------------------------------------------------还书 booklink B; bookdate* Bp = NULL; userbooklink U; userbook* Up = NULL; string bookname; string bookwriter; int sum = 0; string name; string phone;int i = 0; cout << "请输入您借的书名"; cin >> bookname; cout << "请输入您借书的作者"; cin >> bookwriter; cout << "请输入您的姓名:"; cin >> name; Bp = B.looklink(bookname, bookwriter); Up = U.looklink(bookname, bookwriter, name); if (Up == NULL) { cout << "系统没有检测到您的借书记录,即将返回" << endl; system("pause"); system("cls"); return; } else { cout << "系统检测到您的借书记录,如下:" << endl; cout << "书名"<<"\t"<<"作者"<<"\t"<<"待还数量"<<endl; cout << Up->getbookname() << "\t" << Up->getbookwriter() << "\t" << Up->getbooksum() << endl; cout << "请输入您要还书的数量:"; while (i < 3) { cin >> sum; if (sum > 0 && sum <= Up->getbooksum()) { break; } else { i++; if (i == 2) { cout << "您多次输入不合法,即将返回主菜单"; system("pause"); system("cls"); return; } cout << "您输入的数量不合法,请重新输入:"; sum = 0; } } U.changesum(bookname,bookwriter,Up->getbooksum()-sum,name); B.rebuildbook(Bp->getname(),Bp->getwriter(),Bp->getsum()+sum,Bp->getbookclass()); cout << "还书成功!"; system("pause"); system("cls"); return; } } //---------------------------------------------------菜单区 char Shield_4() { char a; while (1) { a = _getch(); if (a >= '1' && a <= '4') { break; } } return a; } char Shield_6() { char a; while (1) { a = _getch(); if (a >= '1' && a <= '6') { break; } } return a; } bool Usermeun() {//用户主菜单 char n;bool k; UserHere: system("cls"); cout << "\n\n\n"; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t--欢迎光临--\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t1.我想借书\t\t\t\t *" << endl;//借书时可以查看图书 cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t2.我想还书\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t3.我想查找书\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t4.退出登录\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl << endl; cout << "————————————————————————————————————————————————————————————"; cout << "请输入您要进行操作对应的编号:"; n = Shield_4(); if (n == '1') { userlendbook(); goto UserHere; } else if (n == '2') { brobook(); goto UserHere; } else if (n == '3') { selectbook(); system("pause"); goto UserHere; } else if (n == '4') { return false; } } bool Admmeun() {//管理员主菜单 char n;bool k; AdmHere: system("cls"); cout << "\n\n\n"; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t--管理员我们又见面了--\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t1.图书入库\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t2.书库查书\t\t\t\t *" << endl;//查看书库中是否有该图书 cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t3.下架图书\t\t\t\t *" << endl;//1.彻底下架(删除图书) 2.下架部分图书(修改图书数量) cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t4.修改图书信息\t\t\t\t *" << endl;//修改图书价格 cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t5.查看书库中所有图书\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t6.退出登录\t\t\t\t *" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl << endl; cout << "————————————————————————————————————————————————————————————"; cout << "请输入您要进行操作对应的编号:"; n = Shield_6(); if (n == '1') {//增 addbook(); system("pause"); goto AdmHere; } else if (n == '2') {//查 selectbook(); system("pause"); goto AdmHere; } else if (n == '3') {//删 delbook(); system("pause"); goto AdmHere; } else if (n == '4') {//改 rebuildbook(); system("pause"); goto AdmHere; } else if (n == '5') {//排序 sortbook(); system("pause"); goto AdmHere; } else if (n == '6') {//回主菜单 return false; } } bool thisMenu(baselink* p) {//登录界面 char n;bool k; Here: system("cls"); cout << "\n\n\n"; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t--欢迎光临--\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t1.登录\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t2.注册\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t3.找回密码\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t4.修改密码\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t5.注销账户\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t6.回主菜单\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl << endl; cout << "————————————————————————————————————————————————————————————"; cout << "请输入您要进行操作对应的编号:"; n = Shield_6(); if (n == '1') {//-----------------------登录 k=landkey(p, '1'); if (k == false) { system("pause"); goto Here; } else { return true; } } else if (n == '2') {//------------------注册 regkey(p); system("pause"); goto Here; } else if (n == '3') {//------------------找回密码 lookpassward(p); system("pause"); goto Here; } else if (n == '4') {//------------------修改密码 landkey(p, '4'); system("pause"); goto Here; } else if (n == '5') {//-------------------注销账户 landkey(p, '5'); system("pause"); goto Here; } else if (n == '6') {//-------------------返回主菜单 return false; } } void mainMenu() {//主菜单 cout << "\n\n\n"; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t--图书管理系统--\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t1.我是用户\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t2.我是管理员\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t3.主题设置\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t4.退出\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *\t\t\t\t\t\t\t\t *" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl; cout << "\t\t\t *---------------------------------------------------------------*" << endl << endl; cout << "————————————————————————————————————————————————————————————"; cout << "请输入您要进行操作对应的编号:"; } //-------------------------------------------------------------辅助功能区 void setColor() { //设置颜色 char n, k; SetColor: system("cls"); printf("1.蓝色系\n2.绿色风格\n3.红色风格\n4.紫色风格\n5.黄色系\n6.还原出厂设置\n剩余颜色还在开发中...\n"); printf("如果想要你自己独特的颜色请联系管理员\n请输入您要换成主题的序号\n"); while (1) { n = _getch(); if (n >= '1' && n <= '6') { break; } } if ('1' == n) system("color 9F"); else if ('2' == n) system("color AE"); else if ('3' == n) system("color CF"); else if ('4' == n) system("color D3"); else if ('5' == n) system("color E5"); else if ('6' == n) system("color 07"); cout << "设置成功!" << endl; printf("点击1返回主菜单\n点击2重新设置主题\n"); while (1) { n = _getch(); if (n == '1' || n == '2') { break; } } if (n == '1') { return; } else if (n == '2') { n = '0'; goto SetColor; } } int main() { baselink* p; Userlink U1; Admlink A1; booklink b; p = &A1; char n;bool k; mainHere: system("cls"); mainMenu(); n = Shield_4(); if (n == '1' || n == '2') { if (n == '1') { p = &U1; } else if (n == '2') { p = &A1; string Admpassward; system("cls"); cout << "请输入管理员密匙:"; cin >> Admpassward; if (Admpassward != "芝麻开门") { cout << "密匙不匹配,您应该不是管理员"; system("pause"); goto mainHere; } } k=thisMenu(p);//登录菜单 if (k == false) { goto mainHere; } else { if (p == &A1) { k=Admmeun(); } else if (p == &U1) { k=Usermeun(); } } if (k == false) { goto mainHere; } } else if (n == '3') { setColor(); goto mainHere; } else if (n == '4') { exit(0); } return 0; }
总结
本项目是在大一上学期学习C++的时候写的课程设计,由于写的仓促难免有些不足,如果大家哪里有疑问请评论区留言或者私信博主。项目中的菜单函数采用了多级嵌套难以理解,大家可以ctrl + 点击响应函数进行跳转理解。希望本博客对大家的求学之路有一定的帮助。如果觉着不错的话留下三连吧(^_−)☆