用户友好图书信息管理系统

本实验报告详述了一个采用自顶向下设计方法的图书信息管理系统,系统包括采编、查询、借阅等功能,并具备操作可撤回性和连贯性。数据库采用NTFS文件流加密,确保安全性。此外,系统对非法输入进行了处理,增强了用户友好性。
摘要由CSDN通过智能技术生成

图书信息管理系统实验报告

一、实验摘要

  实现一个图书信息管理系统,实现的功能有采编、查询和借阅、还书与续借、书目删除、以及管理员直接操作数据库的模式。本程序的几处特色是处理输入不符合规范的字符(串)、代码重用、数据即时更新、根据当前窗口状态将主窗口与其它窗口的并行输出、操作的可撤回性和连惯性,以及数据库的保护隐藏。

二、实验平台

机型:ThinkPad E465 | 系统:Win10 | 软件:记事本、cmd | 编译环境:G++

三、实验目的

1、通过构造数据库加深对数据结构的认识,主要是自定义类与结构体的实现使用。
2、加深对数据遍历方式的认识,这里主要用到了线性遍历。
3、掌握线性表的优化,如存储空间上的优化、查找性能上的优化等。

四、实验原理

  • 总体来看,本程序采用自顶向下的设计方法,先确定管理系统的大致框架,即一个主窗口加上采编、查询和借阅、还书与续借、书目删除、以及管理员直接操作数据库的模式的窗口,再实现各窗口的布局和功能,最后定义一个Database类以及相关全局变量逐个实现这些功能。

  • Database类中包括自定义的书籍结构体数组用于存放书籍名称、作者、出版社、借阅情况等信息,以及辅助变量记录书本书目数量、书本总量、书本剩余量等,类的方法实现了如上所述功能,此外还有一些用于判断状态、选择相应选项的全局变量,在后面解释各个函数的功能时会一一介绍。

  • 在数据库的安全方面。本系统的数据库文件采用了NTFS文件流加密,即只能通过本系统访问这个数据库,从系统外部不能轻易打开并修改数据库文件内的重要数据(当然,如果懂得相关技术可以将此文件解密出来进行修改)。把数据库打包成压缩文件时需在“高级”选项中勾选“保存文件流数据”才能保证数据库的完整。这样提高了数据库的安全性。此外,在每个功能结束后即时重写数据库文件,更新数据库,避免系统突发故障中止时丢失数据。

  • 根据窗口状态来输出各个窗口。这里将各个功能窗口用各个函数实现(包括主窗口),用一个while(now != m_exit){…}循环无限执行判断窗口状态(now)的命令,再根据now的值调用各个窗口的函数,该循环是系统的核心。当然,当窗口状态now被标记为m_exit时,退出该循环,即意味着退出系统。通过状态判断来输出各个窗口有一个好处,那就是可以方便地在各个窗口间调换:当从一个窗口退出时,根据选择将窗口状态now设置为其他窗口的状态,只要该状态不是m_exit,就可以在main()中下一轮循环中执行相应的窗口。一般由主窗口跳到其他窗口的选择是最多的,而其他窗口在结束时将窗口状态now标记为main_w以返回主窗口,也有标记成m_exit的情况以直接退出系统。

  • 代码重用。本程序中大量重复的多选项的选择操作(在0,1,2,…,n中选择)、Yes/No选择,与即时保存数据库文件等操作各只用一个函数实现,在需要的时候调用这些函数;比如多项操作选择函数,先在Database.h头文件中定义void MyChoice(int csmall, int cbig);其中csmall 是选项容许的最小值,cbig是选项容许的最大值,当用户的选项超出最小值到最大值的范围时,就会处理这个错误的输入,这样就可以根据每个窗口中列出的选项灵活地使用该函数来选择,再根据全局变量中的mychoice变量(在本函数中的选择结果保存在此变量中)来运行相应选项对应的函数。在编写程序时考虑代码重用带来了巨大的便利,让我把更多的精力投入到其他函数的设计上。

  • 非法输入的处理是本系统的一大特色。本系统对于不符合规范的输入有过滤和重新输入两种处理方式。当一次输入带有空格的内容时,一般会把空格后的的内容当成下一次输入,造成不可测的混乱,于是在每次输入后采用guolv()这个函数进行过滤,原理是
    while(std::cin.get() != ‘\n’);

    将第一个空格后到回车之间的输入都过滤掉了。Guolv()函数的重用率也是非常高的。除了过滤之外,选择选项(0,1,2,…,n或者[Y/N])时对于不符合选项的输入采取了提示重新输入的办法,这样做的基础是将输入当成是一个std::string类的输入,再对该std::string变量进行合法性分析。非法输入的处理健壮了程序,使用户只能按规定输入,避免不可知的错误。

  • 操作的可撤回性与连惯性是本系统的一大特色。
    • 在设计上实现进行了下述功能,使得几乎在任何时刻都可以即时返回与撤销操作:
      • 在采编未将书名、作者、出版社都没有输入完毕时,可通过输入exit返回主窗口;
      • 在借阅书籍、归还、续借、逐本删除时均可输入0撤消当前操作;
      • 在逐本删除功能结束后会提示是否保存,选择不保存就相当于没有进行删除操作;
      • 在进行一些重要操作时会提示是否进行该操作。
        如此,使人为操作造成的失误可即时撤回,提高操作的安全性。
    • 在操作的连惯性方面,有如下设计:
      • 在有可能需要连续操作的功能中引入循环,通过判断是否继续(Yes_or_Not())来决定下一步是退出该功能还是继续该功能,如可以继续查询、继续借阅、继续归还、继续续借、继续删除……
      • 将查询与借阅功能归并,在查询后提供“借阅”的选项,用户选择该选项即可马上借阅搜寻到的书籍;
      • 大部分窗口和功能中都有“返回主菜单”或“退出”的选项,使用户无需一步一步返回上一级再进行其他选项或退出,一步直达。
        如此,提高了系统的用户友好程度,更加方便用户使用。

  • 管理员模式[*]。管理员模式下可以直接操作数据库文件,即把数据库文件打开,直接修改其中的数据,这个也只有管理员才看得懂了。打开之前需输入管理员密码,关闭数据库文件后提示“数据库已改变,是否重新载入?”,这么做也是减小修改失误带来的风险。输入密码也是删除书目[*]和清空数据库[*]这两个重要功能的必经之路。

五、实验内容

非法输入的纠正:当输入非指定选项时提示重新输入
这里写图片描述
带空格输入的过滤:只认定第一个输入是有效的
这里写图片描述
这里输入了一串从1-10的选项,但只有第一项是有效的,所以选择了第一项“采编”,如下图。
这里写图片描述
功能的连惯性:执行功能后提示是否继续
这里写图片描述
功能的可撤消性:
输入0返回:如下图,不小心进入了借阅选项后可以输入0返回
这里写图片描述
删除书目的可撤消性:如下图,在误删书目后,可以选择不保存来撤消之前的删除操作
这里写图片描述
从系统外部打开数据库文件:不显示数据库内容。(若想打开,需在cmd下用

notepad database.dat:data.txt

此命令打开)
主窗口:与其他窗口同级,只是使用率大。
这里写图片描述
采编:当输错了书籍信息时,可通过即时输入exit返回(注意最迟是在输入出版社名称时可撤回,到了之后选择书籍类别就不能撤回了)
这里写图片描述
查询:查询成功之后会显示书目的详细信息,包括书名、作者、出版社、借阅情况等
书名是模糊查找方式:如下图,按书名查找,输入“自然”二字可以查找到《自然哲学中的数学原理》一书,此外书名、作者、出版社查询均不区分大小写
这里写图片描述
这里写图片描述
按类别查找:可通过输入相应书目类别的序号进行查找,注意最多只能显示10本相应的书目
这里写图片描述
借阅:在查询操作之后,选择2即可借阅,也可继续查询、返回主界面或者退出等
这里写图片描述
还书:需要输入借阅者姓名,之后按本显示读者的借阅情况,在输入显示的书目序号之后,该书籍即被归还(在该书籍下方会显示“已归还”),之后提示是否继续归还,输入0也可退出归还
这里写图片描述
这里写图片描述
续借:与归还类似,需要输入读者的姓名,之后列出读者所有借阅过的书籍,通过输入书籍的序号对相应书籍进行续借,续借后可选择是否继续续借
这里写图片描述
这里写图片描述
删除:
按本删除:在输入管理员密码密码列出了所有
这里写图片描述
清空数据库:像这种重要的操作,首先提示是否继续,再输入管理员密码,如果密码错误,则可输入exit返回
这里写图片描述
管理员模式:输入管理员密码,打开数据库文件,可在此文件中修改管理员密码,在此模式下一定要谨慎修改内容,防止数据被改得不完整而造成重新载入时系统崩溃
这里写图片描述
在关闭数据库文件时,系统提示是否重新载入信息,若不重新载入,则之前的修改作废,数据库仍然为修改前的内容
这里写图片描述
若重新载入,则提示是否继续,若选择退出,可直接退出系统,否则返回主菜单
这里写图片描述
代码重用:下述代码(函数)的重用率极高

void MyChoice(int csmall, int cbig);
//选择选项,修改的全局变量:mychoice
void guolv(); 
//每次输入后,过滤空格后的输入
void Yes_or_Not();
//多用在是否继续的判断上,全局变量:yes
void Database::saveNoneWord();
//各种操作后即时将数据保存至数据库

六、实验总结

本实验最大的体会是自顶向下设计的设计方式,首先明确各个功能,再明确各个功能的函数实现,由总体规划(各个窗口的显示、转换)到各个细节的实现(各个功能用类,函数来实现)。在细节上采用代码重用使设计更加简洁高效。
学会了使程序输入更加健壮的做法。通过过滤、判断std::string类输入是否符合规范来纠正输入错误。一系列用户友好设计,连惯性、可即时撤回性的实现,让用户使用起来更加方便。
在时间复杂度方面,主要体现在查找书籍方面,在查找书籍上使用线性探索,时间复杂度为O(N),空间复杂度为O(1)。储存上的复杂度为O(M),M为总书本数量。

七、参考文献

  1. C++string中用于查找的find系列函数浅析 - 同勉共进 - 博客园
  2. c++输入隐藏密码的实现 - CSDN博客
  3. C++中如何用cout实现输出的填充,宽度,对齐及其精度控制 - PrConstantin - CSDN博客
  4. NTFS交换数据流隐写的应用 - Chesky - 博客园
  5. string::find - C++ Reference
  6. 隐写NTFS STREAM - CSDN博客

八、代码

// Database.h
#ifndef DATABASE_H_
#define DATABASE_H_

#include <string>
#include <windows.h>
#include <time.h>
#include <conio.h>

#define PWDLENTH 100
#define MAX_NUM 200
#define MAX_BOOK 100000
#define PAUSETIME 1000
#define FILEPATH "database.dat:data.txt"
#define UNSECRET_PATH "database.dat"
#define EXIT "exit"
#define TYPE_NUM 12
#define FIND_TYPE 10
#define DEFAULT_PASSWORD "12345678"

typedef struct kuChun{
    bool used;
    std::string reader;
    int year, month, day;
}kuChun;

typedef struct Book
{
    std::string name;
    std::string writer;
    std::string company;
    int type;
    int ku_num;
    int left;
    kuChun ku[MAX_NUM];
}Book;

typedef struct Record{
    int book_no;
    int ku_no;
}Record;

class Database
{
private:
    Book book[MAX_BOOK];
    int book_num;
    int book_all;
    int book_left;
    void delayThirty(int, int);
    Record book_record[MAX_NUM];
    int record;
public:
    int getBook_num();
    int getBook_all();
    int getBook_left();
    int find_add[MAX_BOOK];
    int find_num;
    void Initial();
    void addBook();
    void saveData();
    void saveNoneWord();
    void borrowBook();
    void backBook();
    void delayBook();
    void find_name();
    void find_writer();
    void find_company();
    void find_n_w();
    void find_n_c();
    void find_w_c();
    void find_n_w_c();
    void find_type();
    void clear();
    void clear_all();
    void showInfo(int);
    void showRecord(int, int);
};

void jiXu();
void jiXu_find();
void jiXuChoice(int, int);
void MyChoice(int, int);
void guolv();
void Yes_or_Not();
void inputPwd(std::string &, int);
std::string trans(std::string);

std::string yes;
Database data;
int mychoice;
int jixu_choice;

enum state{mainw, find_borrow, add, del, back_delay, m_exit, admin};
state now;

enum find_state{finding, f_exit};
find_state now_find;

enum back_state{backing, b_exit};
back_state now_back;

enum del_state{deling, d_exit};
del_state now_del;

std::string types[TYPE_NUM] = {
    "[1.科学百科]", "[2.历史文献]", "[3.小说    ]", "[4.期刊报纸]",
    "[5.计算机  ]", "[6.数理    ]", "[7.哲学    ]", "[8.天文    ]",
    "[9.机械    ]", "[10.经济   ]", "[11.语言   ]", "[12.其它   ]"
};

SYSTEMTIME st = {
  0};

std::string add_name;
std::string add_writer;
std::string add_company;

std::string PASSWORD;

#endif // DATABASE_H_
// Database.cpp
#include "Database.h"
#include <iostream>
#include <fstream>
#include <cstdlib>

int Database::getBook_num(){
    return book_num;
}
int Database::getBook_all(){
    return book_all;
}
int Database::getBook_left(){
    return book_left;
}

std::string trans(std::string origin){
    for (int i = 0; i < origin.length(); i ++)
        if (origin[i] >= 'a' && origin[i] <= 'z')
            origin[i] -= 'a' - 'A';
    return origin;
}

void guolv(){
    while (std::cin.get() != '\n');
}

void MyChoice(int csmall, int cbig){
    std::string str;
    while(std::cin >>
基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip 【备注】 1、该资源内项目代码百分百可运行,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值