设计并实现一个书店管理系统,最终交接物为开发文档和源代码。关于程序有以下要求:
- 编程语言限制:软件主体(除 bonus 部分外)完全使用 C++ 编写;
- 程序数据需要记录到文件;
- 程序首次运行时自主执行所需的初始化操作;
- 创建帐户名为
root
,密码为sjtu
,权限为 {7} 的超级管理员帐户。
- 创建帐户名为
- 程序启动后,根据输入数据执行对应操作,直至读入 EOF 或根据相关指令要求终止运行。
使用命令行(Windows CMD 或 Linux Terminal)进行操作,输入数据以换行符或回车符为分隔为若干指令。
指令合法字符集为标准 ASCII 字符;允许的空白符仅为空格,单个指令被空格分割为多个部分。多个连续空格效果与一个空格等价;行首行末允许出现多余空格;如无特殊说明禁止省略或另增空格。
指令中第一个部分必须为指令关键词,指令中关键词部分必须与指令格式完全匹配。
本文档中以弱化的正则语法说明指令文法。合法指令的文法相关说明如下:
[x]
表示一串有特定限制的用户自定义字符串;(a|b|c)
表示此处仅能出现a
,b
,c
中其一;(x)?
表示此处可以出现零次或一次x
;(x)+
表示此处可以出现一次或多次x
。
合法的指令如下所示:(#
开头的行是注释)
# 基础指令
quit
exit
# 帐户系统指令
su [UserID] ([Password])?
logout
register [UserID] [Password] [Username]
passwd [UserID] ([CurrentPassword])? [NewPassword]
useradd [UserID] [Password] [Privilege] [Username]
delete [UserID]
# 图书系统指令
show (-ISBN=[ISBN] | -name="[BookName]" | -author="[Author]" | -keyword="[Keyword]")?
buy [ISBN] [Quantity]
select [ISBN]
modify (-ISBN=[ISBN] | -name="[BookName]" | -author="[Author]" | -keyword="[Keyword]" | -price=[Price])+
import [Quantity] [TotalCost]
# 日志系统指令
show finance ([Count])?
log
report finance
report employee
在用户输入一条指令后,如果合法则执行对应操作,如果有则输出操作结果;如果指令非法或操作失败则输出 Invalid\n
。仅有空格的指令合法且无输出内容。
除非有特殊说明,如果输入指令对应的输出内容非空,则结尾有 \n
字符;输出内容为空则不输出任何字符。
quit
和 exit
指令功能为正常退出系统。
书店管理系统服务于 店主(超级管理员),员工(管理员)以及顾客(用户)。为满足其不同需求,故需帐户系统管理帐户及权限数据,并提供相应功能。
本文档中以 {x} 表示权限等级,数字越大则权限越高。帐户的权限等级有 {7}, {3} 和 {1};未登录任何帐户的状态下当前帐户权限视为 {0}。低权限帐户能够访问的功能严格是高权限帐户能够访问的功能的子集,指令的权限等级表示能够执行该指令的最低当前帐户权限需求。换句话说,高权限的帐户可以执行需要低权限的指令,反之则不可。
- 店主 {7}:使用
root
帐户,可以访问书店系统所有功能,包括日志和帐户管理功能; - 员工 {3}:可以访问修改图书数据相关功能等;
- 顾客 {1}:可以注册帐户,查询、购买图书;
- 游客 {0}:可以注册帐户。
本系统中有且仅有以上四种权限等级,其余权限等级非法。
系统支持嵌套登录,即允许多个帐户同时处于登录状态;允许同一帐户同时多次登录。输入的指令视为最后登录的帐户操作。退出系统视为登出所有已登录帐户。
示例:(假设所有用户均存在,所有密码均正确)
# 初始时登录栈为空
su root sjtu
select first
# 此时登录栈为 root,选择的书为 first
su root sjtu
# 此时登录栈为 root root,没有选择的书
select second
su zhang beihai
select third
# 此时登录栈为 root root zhang,选择的书为 third
# 操作的用户为 zhang,无法执行 delete 等命令
su chu yan
# 此时登录栈为 root root zhang chu,操作的用户为 chu,没有选择的书
logout
# 此时登录栈为 root root zhang,选择的书为 third
logout
# 此时登录栈为 root root,选择的书为 second
logout
# 此时登录栈为 root,选择的书为 first
关于指令格式中的用户自定义字符串限定如下,其中「最大长度」含义为该字符串所占存储空间不能超过指定数目的英文字母字符所占存储空间。
[UserID]
,[Password]
,[CurrentPassword]
,[NewPassword]
- 合法字符集:数字,字母,下划线;
- 最大长度:30。
[Username]
- 合法字符集:除不可见字符以外 ASCII 字符;
- 最大长度:30。
[Privilege]
- 合法字符集:数字;
- 最大长度:1。
出现不符合上述限定的自定义字符串的指令视为非法,下同。
本文档中指令说明格式如下:
- 指令名称
- {指令权限}
[指令格式]
- 指令功能
- 指令逻辑(条数不定,各逻辑间优先顺序同列举顺序)
- {指令权限}
以下为指令说明。
- 登录帐户
- {0}
su [UserID] ([Password])?
- 使登录帐户变为已登录状态,当前帐户变为该帐户。
- 如果该帐户不存在则操作失败;
- 如果密码错误则操作失败;
- 如果当前帐户权限等级高于登录帐户则可以省略密码。
- {0}
- 注销帐户
- {1}
logout
- 撤销最后一次成功执行的
su
指令效果。- 如无已登录帐户则操作失败。
- {1}
- 注册帐户
- {0}
register [UserID] [Password] [Username]
- 注册信息如指令格式所示,权限等级为 {1} 的帐户。
- 如果
[UserID]
与已注册帐户重复则操作失败。
- 如果
- {0}
- 修改密码
- {1}
passwd [UserID] ([CurrentPassword])? [NewPassword]
- 修改指定帐户的密码。
- 如果该帐户不存在则操作失败;
- 如果密码错误则操作失败;
- 如果当前帐户权限等级为 {7} 则可以省略
[CurrentPassword]
。
- {1}
- 创建帐户
- {3}
useradd [UserID] [Password] [Privilege] [Username]
- 创建信息如指令格式所示的帐户。
- 如果待创建帐户的权限等级大于等于当前帐户权限等级则操作失败;
- 如果
[UserID]
与已注册帐户重复则操作失败。
- {3}
- 删除帐户
- {7}
delete [UserID]
- 删除指定帐户。
- 如果待删除帐户不存在则操作失败;
- 如果待删除帐户已登录则操作失败。
- {7}
图书系统提供图书信息、库存信息和图书交易财务记录的相关服务及数据存储功能。
[ISBN]
:Internal Strange Book Number;- 合法字符集:除不可见字符以外 ASCII 字符;
- 最大长度:20;
- 特殊说明: 本系统中任何两本图书不应有相同
[ISBN]
信息。
[BookName]
,[Author]
:图书名字,图书作者名字;- 合法字符集:除不可见字符和英文双引号以外 ASCII 字符;
- 最大长度:60。
[Keyword]
:图书关键词;- 合法字符集:除不可见字符和英文双引号以外 ASCII 字符;
- 最大长度:60;
- 特殊说明:
[keyword]
内容以|
为分隔可以出现多段信息。如math|magic|quantum
表示该图书具有三个无顺序的关键词math
,magic
和quantum
,每段信息长度至少为 1。
[Quantity]
:购买数量;- 合法字符集:数字;
- 最大长度:10;
- 特殊说明:数值不超过 2'147'483'647。
[Price]
,[TotalCost]
:图书单价,交易总额。- 合法字符集:数字和
.
; - 最大长度:13;
- 特殊说明:本系统中浮点数输入输出精度固定为小数点后两位。
- 合法字符集:数字和
字符相关信息默认值为空,数字相关信息默认值为数值 0。
-
检索图书
- {1}
show (-ISBN=[ISBN] | -name="[BookName]" | -author="[Author]" | -keyword="[Keyword]")?
- 以
[ISBN]
字典升序依次输出满足要求的图书信息,每个图书信息输出格式为[ISBN]\t[BookName]\t[Author]\t[Keyword]\t[Price]\t[库存数量]\n
,其中[Keyword]
中关键词顺序为输入时的顺序。- A无满足要求的图书时输出空行;
- 无附加参数时,所有图书均满足要求;
- 附加参数内容为空则操作失败;
[Keyword]
中出现多个关键词则操作失败。
- {1}
-
购买图书
- {1}
buy [ISBN] [Quantity]
- 购买指定数量的指定图书(由于本系统不包括支付系统,故仅需减少库存),以浮点数输出购买图书所需的总金额。
- 没有符合条件的图书则操作失败;
- 购买数量为非正整数则操作失败。
- {1}
-
选择图书
- {3}
select [ISBN]
- 以当前帐户选中指定图书(帐户登出后无需保存选中图书情况)。
- 没有符合条件的图书则创建仅拥有
[ISBN]
信息的新图书; - 退出系统视为取消选中图书。
- 没有符合条件的图书则创建仅拥有
- {3}
-
修改图书信息
- {3}
modify (-ISBN=[ISBN] | -name="[BookName]" | -author="[Author]" | -keyword="[Keyword]" | -price=[Price])+
- 以指令中的信息更新选中图书的信息。
- 如未选中图书则操作失败;
- 有重复附加参数为非法指令;
- 附加参数内容为空则操作失败;
- 不允许将 ISBN 改为原有的 ISBN,例如:
为非法操作;
select example modify -ISBN=example
[keyword]
包含重复信息段则操作失败。
- {3}
-
图书进货
- {3}
import [Quantity] [TotalCost]
- 以指定交易总额购入指定数量的选中图书,增加其库存数。
- 如未选中图书则操作失败;
- 购入数量为非正整数则操作失败;
- 交易总额为非正数则操作失败。
- {3}
日志系统负责记录书店管理系统运行过程中的各种数据,提供各类日志信息查询服务
[Count]
:交易笔数- 合法字符集:数字;
- 最大长度:10;
- 特殊说明:数值不超过 2'147'483'647。
-
财务记录查询
- {7}
show finance ([Count])?
- 输出最后完成的指定笔数交易总额,格式为
+ [收入] - [支出]\n
,例如+ 1.23 - 45678.90
。- 无
Count
参数时,输出所有交易之总额;- 不存在交易时认为收入支出均为 0.00。
Count
为 0 时输出空行;Count
大于历史交易总笔数时操作失败。
- 无
- {7}
-
生成财务记录报告指令 - {7}
report finance
🎗️ - 生成一张赏心悦目的财务报表,格式自定- 生成全体员工工作情况报告指令
- {7}
report employee
🎗️ - 生成一张赏心悦目的员工工作情况表,记录其操作,格式自定
- {7}
- 生成全体员工工作情况报告指令
-
生成日志
- {7}
log
🎗️ - 返回日志记录,包括系统操作类的谁干了什么,以及财务上每一笔交易情况,格式自定。
- {7}
-
注意:带有 🎗️ 标记的指令不会出现在测试数据中,但需要实现并手动向助教展示。
考虑到应用场景下帐户和图书数量较大,故禁止将主体数据存储于内存,应实时读写文件数据。运行过程中程序创建的文件数量不得超过 20 个。
禁止类似 filesystem as database 的实现方式。(如果你不知道这是什么意思,那么也不用担心自己会触犯该条要求。)