C++课程设计:图书管理系统

课程设计目的

作为软件工程和计算机科学与技术专业的基本课程,课程设计不仅涵盖了C++语言的知识体系,又与工程的实际需要切实相关。通过课程设计的综合性训练,对开发者解决实际问题能力,编程能力,动手能力有很大的提升,更有助于样成良好的编程习惯

图书管理系统需求分析

某高校为更好的管理图书馆,现需设计一简易图书管理系统,实现新书录入,图书资料查询,显示总图书信息功能。要求开发的系统需要具备以下功能:

1.实现读者借阅图书;
2.实现读者归还图书;
3.实现对图书信息的综合管理: (设置二级子目录实现信息的增,删,改,查等操作)
4.实现对读者信息的综合管理: (设置二级子目录实现信息的增,删,改,查等操作)
5.显示用户信息:显示所有用户信息,含学号、姓名、借阅状况等信息;
6.返回主界面;

设计实现

本部分设计内容包括:类的设计、数据成员设计、成员函数设计,以及主程序设计(模块函数实现,主函数) 【源码中详细解释,此处不作赘述】

头文件

  • book.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#pragma once   //包含此语句的文件只会被编译一次,表示在编译时, 该文件只被包含一次, 减少整个编译过程中打开该文件次数

//图书管理模块
//图书类
class book {
public:
int no; //图书编号
char name[20]; //图书名称
int b_flag; //1:在架 2:借出
int b_del; //1:存在 2:删除
public:
book() {} //无参构造函数
void setno(int n); //设置图书编号
int getno(); //返回图书编号值
void setname(char na[]);
char* getname(); //返回图书名称
void borbook();
void delbook();
void addbook(int no, char na[]); //增加图书功能
};

//图书数据库类
const int BMAX = 50; //定义书本最大值
class bdatabase {
public:
book btarray[BMAX]; //图书集合
int top;
public:
bdatabase();
~bdatabase(); //析构函数,将btarray[]写到book.txt文件中
void addbooks(); //在图书数据库中添加图书
int findbooks(int suffix); //查找图书,该函数用于借书操作,suffix是数组下标
int findbooks(); //查找图书,该函数用于图书维护
void editbooks(); //编辑图书
void delbooks(); //删除图书
void listbooks(); //显示全部图书
};

void booksmanage(); //图书信息管理界面 声明
void borrow_or_return(char br);
  • interface.h
1
2
3
4
5
6
7
#pragma once

void login();
void Main_Interface();
void Book_Maintenance_Interface();
void Reader_Maintenance_Interface();
void UI();
  • reader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#pragma once

#include"book.h"

//读书管理模块
//读者类
class reader {
public:
int no;
char name[20];
int r_del; //1存在 2删除
int r_bor; //1借过书 2未借书
book brbook;
public:
void addreader(int id, char na[]); //增加读者
void setbrbook(book bt); //设置借书标记
book getbrbook() {
return brbook; //返回借书信息
}
};

//读者数据库类
class rdatabase {
public:
reader rdarray[BMAX];
int top;
public:
rdatabase();
~rdatabase();
void addreaders(); //添加读者
int findreaders(int suffix); //查找读者,该函数用于借书还书操作,suffix是数组下标
int findreaders(); //查找读者,该函数用于读者维护操作
void editreaders(); //编辑读者信息
void delreaders(); //删除读者,读者如果借书,需要还书后才能删除
void listreaders(); //显示所有读者
};

void readersmange();

函数实现

  • main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
using namespace std;

#include "interface.h"
#include "reader.h"

int main() {
char in = -1; //因为VS环境不能使用为初始化的变量,所以首先赋值为不可能使用的变量值以通过编译 char in=-1
login();
do{//退出系统限制条件
UI(); //系统界面改变
Main_Interface();
cin >> in;
switch (in) {
case'1':
borrow_or_return(in);
break;
case'2':
borrow_or_return(in);
break;
case'3':
booksmanage();
break;
case'4':
readersmange();
break;
case'0': {
cout << "感谢您使用本系统,再见!" << endl;
break;
}
default:
cout << "In Put Error!!! Please try again!!!" << endl;
}
} while (in != '0');
return 0;
}
  • book.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#include <iostream>
using namespace std;
#include <fstream>
#include <cstring>

#include "interface.h"
#include "reader.h"

//图书管理模块

//图书类函数实现
void book::setno(int n) {
no = n;
}

int book::getno() {
return no;
}

void book::setname(char na[]) {
strcpy_s(name, na);
}

char* book:: getname() {
return name;
}

void book::borbook() {
b_flag = 2; //借书标志
}

void book::delbook() {
b_del = 2; //删除标志
}

void book::addbook(int no, char na[]) {
setno(no);
setname(na);
b_flag = 1;
b_del = 1;
}

//图书数据库类
bdatabase::bdatabase() {
book b; //建立book类对象并b
top = -1; //数组下标从0开始,此处top值置为-1可保证从数组第一个元素开始存储信息
fstream file("book.txt", ios::in);//打开文件进行读操作,若文件不存在则出错.输入输出指:内存与硬盘间的信息传递
while (1) {
file.read((char*)&b, sizeof(b));//从文件中读取b个字符到char*指向的缓存中(book类对象b的地址)
if (!file) //若读取到文件尾EOF,返回非0值(一般为1),结束书本数量的计数,关闭文件
break;
top++;
btarray[top] = b;
}
file.close();
}

bdatabase::~bdatabase() {
fstream file("book.txt", ios::out);//输出:内存->硬盘
for (int i = 0; i <= top; i++) {
if (btarray[i].b_del == 1)
file.write((char*)&btarray[i], sizeof(btarray[i]));
}
file.close();
}

void bdatabase::addbooks() {
book bk; //创建book类对象bk
int no; //书号
char bname[20]; //书名 用数组存放
cout << "请输入书号:";
cin >> no;
cout << endl << "请输入书名:";
cin >> bname;
cout << endl;
bk.b_flag = 1;
bk.addbook(no, bname); //类中成员函数addbook(),设置书号与书名 修改标志
top++;
btarray[top] = bk;
return; //返回上个操作界面
}

int bdatabase::findbooks(int suffix) {
int no;
cout << "请输入书号:";
cin >> no;
for (int i = 0; i <= top; i++) {
if (btarray[i].no == no && btarray[i].b_del == 1) {
return i;
}
}
return -1;
}

int bdatabase::findbooks() {
int no;
char value[6];
cout << "请输入书号:";
cin >> no;
for (int i = 0; i <= top; i++) {
if (btarray[i].no == no && btarray[i].b_del == 1) {
if (btarray[i].b_flag == 1)
strcpy_s(value, "在架");
if (btarray[i].b_flag == 2)
strcpy_s(value, "借出");
cout << "书号:" << btarray[i].no << " " << "书名:" << btarray[i].name << " " << "图书状态:" << value << endl;
return i;
}
}
return -1;
}

void bdatabase::editbooks() {
int cur;
cur = findbooks();
if (cur == 1) {
cout << "该书不存在" << endl;
return;
}
cout << "当前图书信息--" << "书号:" << btarray[cur].no << " " << "书名:" << btarray[cur].name << endl;
cout << endl;
cout << "请继续操作以修改图书信息" << endl;
cout << endl << "书名:";
cin >> btarray[cur].name;
return;
}

void bdatabase::delbooks() {
int cur;
cur = findbooks();
if (cur == 1) {
return;
}
if (btarray[cur].b_flag == 2) { //删除时判断图书是否借出
cout << "该图书已经借出,请归还后删除!" << endl;
return;
}
btarray[cur].b_del = 2;
return;
}

void bdatabase::listbooks() {
char value[6];
for (int i = 0; i <= top; i++) {
if (btarray[i].b_del == 1) {
if (btarray[i].b_flag == 1)
strcpy_s(value, "在架");
if (btarray[i].b_flag == 2)
strcpy_s(value, "借出");
cout << "书号:" << btarray[i].no << "书名:" << btarray[i].name << "图书状态:" << value << endl;
}
}
return;
}

void borrow_or_return(char br) { //借书、还书函数,参数br:判断 “借书”,“还书”. 1 借书 2 还书
int reader_ID = 0; //读者id
int book_ID = 0; //书的id
int rsuffix, bsuffix;
bdatabase t_bd;
rdatabase t_rd;
if (br == '1') { //借书
rsuffix = t_rd.findreaders(reader_ID);
bsuffix = t_bd.findbooks(book_ID);
if (rsuffix == -1 || bsuffix == -1)
return;
if (t_bd.btarray[bsuffix].b_flag == 2) {
cout << "图书已经借出,请选择其它图书" << endl;
return;
}
t_bd.btarray[bsuffix].b_flag = 2;
t_rd.rdarray[rsuffix].r_bor = 1;
t_rd.rdarray[rsuffix].brbook = t_bd.btarray[bsuffix];
return;
}
if (br == '2') {
rsuffix = t_rd.findreaders(reader_ID);
bsuffix = t_bd.findbooks(book_ID);
if (rsuffix == -1 || bsuffix == -1)
return;
if (t_rd.rdarray[rsuffix].brbook.no == t_bd.btarray[bsuffix].no) {
t_bd.btarray[bsuffix].b_flag = 1;
t_rd.rdarray[rsuffix].r_bor = 2;
t_rd.rdarray[rsuffix].brbook = t_bd.btarray[bsuffix];
}
else {
cout << "请重新输入,读者借阅图书书号错误" << endl;
return;
}
return;
}
}

void booksmanage() {
char in;
bdatabase bd;
do {
system("pause");
system("cls");//切换UI时,刷新缓冲区当前内容,完成下次更新
UI();
Book_Maintenance_Interface();
cin >> in;
switch (in) {
case'1':
bd.addbooks();
break;
case'2':
bd.editbooks();
break;
case'3':
bd.delbooks();
break;
case'4':
bd.findbooks();
break;
case'5':
bd.listbooks();
break;
case'6':
break;
default:
cout << "In Put Error!!! Please try again!!!" << endl;
}
} while (in != '6');
return;
}
  • interface.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
using namespace std;
#include <cstdlib> //system() 库

void login() {
char passward[2] = "2"; //此变量用于存储登录密码
char s[2];//获取输入的密码,用于验证和登录密码是否相同
int n = 3; //限定输入错误次数是3次
cout << "请输入登录密码: ";
cin >> s;
if (!strcmp(s, passward)) { //若密码正确
cout << "恭喜您登陆成功!!!请稍等......\n\n";
system("pause");
}
else {
cout << "Waring!!!密码输入错误,请退出系统后重新尝试\n";
system("pause");
exit(0);
}
}

void Main_Interface() { //主界面
system("cls"); //清屏函数 clean screen
system("title 图书管理系统 项目开发人员 : XXX ");//对控制台文件名重命名
cout << "\n\n\n\n\n";
cout << "\t\t\t***************欢 迎 进 入 图 书 管 理 系 统***********************\n";//与case顺序一致
cout << "\t\t\t*\t 1. 借书 * \n ";
cout << "\t\t\t*\t 2. 还书 * \n ";
cout << "\t\t\t*\t 3. 图书信息管理 * \n ";
cout << "\t\t\t*\t 4. 读者信息管理 * \n ";
cout << "\t\t\t*\t 0. 退出 * \n ";
cout << "\t\t\t*******************************************************************\n ";
cout << " ";
cout << "\t\t\t Copyright (C) 2020-2021. All Rights Reserved \n ";
cout << "\t\t\t\n请选择您要执行的操作编号(1-4-0): ";
cout << endl;
}

void Book_Maintenance_Interface() { //图书维护子菜单
cout << "\n\n\n\n\n";
cout << "\t\t\t***************图 书 信 息 维 护 管 理 员 后 台********************\n";//与case顺序一致
cout << "\t\t\t*\t 1. 添加 * \n ";
cout << "\t\t\t*\t 2. 修改 * \n ";
cout << "\t\t\t*\t 3. 删除 * \n ";
cout << "\t\t\t*\t 4. 查找 * \n ";
cout << "\t\t\t*\t 5. 显示 * \n ";
cout << "\t\t\t*\t 6. 返回上级操作 * \n ";
cout << "\t\t\t*******************************************************************\n ";
cout << " ";
cout << "\t\t\t\n请选择您要执行的操作编号(1-6): ";
cout << endl;
}

void Reader_Maintenance_Interface() { //读者维护子菜单
cout << "\n\n\n\n\n";
cout << "\t\t\t***************读 者 信 息 维 护 管 理 员 后 台********************\n";//与case顺序一致
cout << "\t\t\t*\t 1. 添加 * \n ";
cout << "\t\t\t*\t 2. 修改 * \n ";
cout << "\t\t\t*\t 3. 删除 * \n ";
cout << "\t\t\t*\t 4. 查找 * \n ";
cout << "\t\t\t*\t 5. 显示 * \n ";
cout << "\t\t\t*\t 6. 返回上级操作 * \n ";
cout << "\t\t\t*******************************************************************\n ";
cout << " ";
cout << "\t\t\t\n请选择您要执行的操作编号(1-6): ";
cout << endl;
}

void UI() //自定义函数实现颜色变化
{
system("color F0");//前景黑 背景亮白 白底黑字
}
  • reader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <fstream>
#include <cstring>
#include <iostream>
using namespace std;

#include "reader.h"
#include "interface.h"

//读书管理模块
//读者类函数实现
void reader::addreader(int id, char na[]) {
no = id;
strcpy_s(name, na);
r_del = 1;
}

void reader::setbrbook(book bt) {
brbook = bt;
}

rdatabase::rdatabase() {
reader rd;
top = -1;
fstream file("reader.txt", ios::in);
while (1) {
file.read((char*)&rd, sizeof(rd));
if (!file) break;
top++;
rdarray[top] = rd;
}
file.close();
}

rdatabase::~rdatabase() {
fstream file("reader.txt", ios::out);
for (int i = 0; i <= top; i++) {
if (rdarray[i].r_del == 1)
file.write((char*)&rdarray[i], sizeof(rdarray[i]));
}
file.close();
}

void rdatabase::addreaders() {
reader rd;
int no;
char rname[20];
cout << "请输入学号:";
cin >> no;
cout << endl << "请输入姓名:";
cin >> rname;
cout << endl;
rd.addreader(no, rname);
rd.r_bor = 2;
top++;
rdarray[top] = rd;
return;
}

int rdatabase::findreaders(int suffix) {
int no;
cout << "请输入学号:";
cin >> no;
for (int i = 0; i <= top; i++) {
if (rdarray[i].no == no && rdarray[i].r_del == 1) {
return i;
}
}
return -1;
}

int rdatabase::findreaders() {
int no;
char value[3];
cout << "请输入学号:";
cin >> no;
for (int i = 0; i <= top; i++) {
if (rdarray[i].no == no && rdarray[i].r_del == 1) {
if (rdarray[i].r_bor == 1)
strcpy_s(value, "借");
if (rdarray[i].r_bor == 2)
strcpy_s(value, "无");
cout << "学号:" << rdarray[i].no << " " << "姓名:" << rdarray[i].name << " " << "是否借书:" << value << endl;
return i;
}
}
return -1;
}

void rdatabase::editreaders() {
int cur;
cur = findreaders();
if (cur == 1) {
cout << "未找到该学生" << endl;
return;
}
cout << "请修改数据:" << endl;
cout << endl << "姓名:";
cin >> rdarray[cur].name;
return;
}

void rdatabase::delreaders() {
int cur;
cur = findreaders();
if (cur == 1) {
return;
}
if (rdarray[cur].r_bor == 1) {
cout << "该用户已借出图书,请归还后删除!" << endl;
return;
}
rdarray[cur].r_del = 2;
return;
}

void rdatabase::listreaders() {
char value[3];
for (int i = 0; i <= top; i++) {
if (rdarray[i].r_del == 1) {
if (rdarray[i].r_bor == 1)
strcpy_s(value, "借");
if (rdarray[i].r_bor == 2)
strcpy_s(value, "无");
cout << "学号:" << rdarray[i].no << " " << "姓名:" << rdarray[i].name << " " << "是否借书:" << value << endl;
}
}
return;
}

void readersmange() {
char in;
rdatabase bd;
do {
system("pause"); //暂停界面,以便显示所需数据
system("cls");
UI();
Reader_Maintenance_Interface();
cin >> in;
switch (in) {
case'1':
bd.addreaders();
break;
case'2':
bd.editreaders();
break;
case'3':
bd.delreaders();
break;
case'4':
bd.findreaders();
break;
case'5':
bd.listreaders();
break;
case'6':
break;
default:
cout << "In Put Error!!! Please try again!!!" << endl;
}
} while (in != '6');
return;
}

注:本程序在Visual Studio 2019正常运行,其他配置环境可能有所差异,有问题的朋友可以留言 / 私信解决,欢迎交流学习