该文主要阐述如何用C++实现简易图书管理系统,实现算法较为暴力,但各功能齐全,适合新手编写

点击查看源码
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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
#include <iostream>
#include <fstream>
using namespace std;

int MAXSIZE = 10;
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct Book{
string id; //图书编号
string name; //图书名称
string press; //出版社
int count; //图书数量
string author; //图书作者
double price; //图书价格
} Book; // 书籍结点

typedef struct {
Book *books;
int length; //图书种类数
}BookList; //图书类别信息

void readFile(BookList & bookList);
Status save(const BookList & bookList);
int queryBook(const BookList & bookList, string value, int flag, bool isNeedPrint);
void printOne(const Book & book);
void printAll(const BookList &bookList);
void deleteBook(BookList & bookList, string id);
void addBook(BookList & bookList);
void modifyBook(BookList & bookList);
void insertSort(BookList & bookList, int flag);
void classify(const BookList & bookList);
void extend(BookList & bookList);
void menu();

void readFile(BookList & bookList){
string filename;
cout << "请输入需要读入的文件名:" << endl;
cin >> filename;
ifstream infile(filename);
if (!infile.is_open())
{
cout << "文件读入失败,请重试!" << endl;
return;
}

int length = bookList.length;
//数据预读入,可能会遇到空间不足问题
while (!infile.eof() && length < MAXSIZE)
{
infile >> bookList.books[length].id >> bookList.books[length].name >> bookList.books[length].press >> bookList.books[length].count
>> bookList.books[length].author >> bookList.books[length].price;
++length;
}
if (!infile.eof())
//无需删除元素,因为之后所有的操作都是根据bookList.length为索引,只要该值不变,内容就可理解为无变化
cout << "空间不足,读入失败!请先扩充空间!" << endl;
else
{
bookList.length = length;
cout << "文件读入成功" << endl;
}
infile.close();
}

Status save(const BookList & bookList)
{
string filename;
cout << "请输入需要保存到的文件名:";
cin >> filename;
ofstream outfile(filename);
if (!outfile.is_open())
{
cout << "文件保存失败,是否退出(Y/N):";
char choice;
if ('Y' == choice || 'y' == choice)
return OK;
else return ERROR;
}
else
{
int length = bookList.length;
for (int i = 0; i < length; ++i)
outfile << bookList.books[i].id << " " << bookList.books[i].name << " " << bookList.books[i].press << " " << bookList.books[i].count << " "
<< " " << bookList.books[i].author << " " << bookList.books[i].price << endl;
cout << "文件保存成功!" << endl;
return OK;
}
outfile.close();
}

// flag = 0, 表示根据id查询;
// flag = 1, 表示根据图书名字查询;
// isNeedPrint, true表示需要打印信息;
int queryBook(const BookList & bookList, string value, int flag, bool isNeedPrint)
{
int length = bookList.length;
//id查询不可能重复
if (0 == flag)
{
for (int i = 0; i < length; i++)
if (value == bookList.books[i].id)
{
if (isNeedPrint)
printOne(bookList.books[i]);
return i;
}
if (isNeedPrint)
cout << "对不起,查无此书!" << endl;
return -1;
}
//书名查询可能重复
else if (1 == flag)
{
Book temp[bookList.length];
int count = 0;
for (int i = 0; i < length; i++)
if (value == bookList.books[i].name)
{
temp[count] = bookList.books[i];
count ++;
}

if (0 == count)
{
if (isNeedPrint)
cout << "对不起,查无此书!" << endl;
return -1;
}
else
{
if (isNeedPrint)
for (int i = 0; i < count; i++)
printOne(temp[i]);
return 1;
}
}
}

void printAll(const BookList &bookList)
{
int length = bookList.length;
for (int i = 0; i < length; ++i)
printOne(bookList.books[i]);
}

void printOne(const Book & book)
{
cout << "书籍ID:" << book.id << " ";
cout << "书籍名称:" << book.name << " ";
cout << "书籍出版社:" << book.press << " ";
cout << "书籍数量:" << book.count << " ";
cout << "书籍作者:" << book.author << " ";
cout << "书籍价格:" << book.price << " " << endl;
}


void deleteBook(BookList & bookList, string id)
{
int position = queryBook(bookList, id, 0, false);
int length = bookList.length;
if (-1 != position)
{
for (int i = position; i < length - 1; i++)
bookList.books[i] = bookList.books[i + 1];
bookList.length --;
cout << "文件删除成功!" << endl;
}
else
cout << "对不起, 查无此书!" << endl;
}

void addBook(BookList & bookList)
{
int length = bookList.length;
if (length >= MAXSIZE)
cout << "空间已满,请先开拓空间!" << endl;
else
{
cout << "请依次输入id、书名、出版社、数量、作者、价格" << endl;
cin >> bookList.books[length].id >> bookList.books[length].name >> bookList.books[length].press
>> bookList.books[length].count >> bookList.books[length].author >> bookList.books[length].price;
if (-1 != queryBook(bookList, bookList.books[length].id, 0, false))
{
cout << "信息添加失败,已存在同id书籍" << endl;
return;
}
bookList.length ++;
cout << "书籍添加成功!" << endl;
}
}

void modifyBook(BookList & bookList)
{
string id;
cout << "请输入需要修改的书籍id:";
cin >> id;
int position = queryBook(bookList, id , 0, false);
if (position == -1)
cout << "对不起,查无此书" <<endl;
else
{
char choice;
cout << "当前书籍名为:" << bookList.books[position].name << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新书名:";
cin >> bookList.books[position].name;

}

cout << "当前书籍出版社为:" << bookList.books[position].press << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新出版社:";
cin >> bookList.books[position].press;
}

cout << "当前书籍数量为:" << bookList.books[position].count << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新数量:";
cin >> bookList.books[position].count;
}

cout << "当前书籍作者为:" << bookList.books[position].author << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新作者:";
cin >> bookList.books[position].author;
}

cout << "当前书籍价格为:" << bookList.books[position].price << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新价格:";
cin >> bookList.books[position].price;
}

cout << "信息修改完毕!" << endl;
cout << "修改后内容为:" << endl;
printOne(bookList.books[position]);
}
}

//flag = 0, 代表按照ID排序
//flag = 1,代表按照价格排序
void insertSort(BookList & bookList, int flag)
{
if (bookList.length == 0)
cout << "当前数据为空" << endl;
else if (bookList.length == 1)
return;
else
{
int length = bookList.length;
if (flag == 0)
{
int i, j;
for (i = 1; i < length; ++i)
if (bookList.books[i].id < bookList.books[i - 1].id)
{
Book temp = bookList.books[i];
for (j = i - 1; j >= 0 && temp.id < bookList.books[j].id; --j)
bookList.books[j + 1] = bookList.books[j];
bookList.books[j + 1] = temp;
}
cout << "已经按照ID升序完成排序!" << endl;
}

if (flag == 1)
{
int i, j;
for (i = 1; i < length; ++i)
if (bookList.books[i].price < bookList.books[i - 1].price)
{
Book temp = bookList.books[i];
for (j = i - 1; j >= 0 && temp.price < bookList.books[j].price; --j)
bookList.books[j + 1] = bookList.books[j];
bookList.books[j + 1] = temp;
}

cout << "已按照价格升序完成排序!" << endl;
}
}

}

void classify(const BookList & bookList)
{
const int length = bookList.length;
if (bookList.length == 0)
cout << "当前数据为空" << endl;
else
{
int i ,j;
Book *books = new Book[length];
for (i = 0; i < length; ++i)
{
books[i] = bookList.books[i];
}

for (i = 1; i < length; ++i)
if (books[i].press < books[i - 1].press)
{
Book temp = books[i];
for (j = i - 1; j >= 0 && temp.press < books[j].press; --j)
books[j + 1] = books[j];
books[j + 1] = temp;
}

cout << books[0].press << ":" << endl;
printOne(books[0]);
for (i = 1; i < length; ++i)
{
if (books[i - 1].press != books[i].press)
cout << books[i].press << ":" << endl;
printOne(books[i]);
}
delete[] books;
}

}

void extend(BookList & bookList)
{
MAXSIZE *= 2;
const int length = bookList.length;
Book *books = new Book[length];
for (int i = 0; i < length; ++i)
{
books[i] = bookList.books[i];
}
delete[] bookList.books;
bookList.books = new Book[MAXSIZE];
for (int i = 0; i < length; ++i)
{
bookList.books[i] = books[i];
}
delete[] books;
cout << "空间已扩大两倍" << endl;
}

void menu()
{
cout << "============1. 文件读入================" << endl;
cout << "============2. 根据ID查询==============" << endl;
cout << "============3. 根据书名查询=============" << endl;
cout << "============4. 添加书籍================" << endl;
cout << "============5. 删除书籍================" << endl;
cout << "============6. 修改书籍================" << endl;
cout << "============7. 根据ID排序==============" << endl;
cout << "============8. 根据价格排序=============" << endl;
cout << "============9. 分类打印=================" << endl;
cout << "============10. 打印全部信息=============" << endl;
cout << "============11. 保存====================" << endl;
cout << "============12. 扩容====================" << endl;
cout << "============0. 退出====================" << endl;
cout << "请选择:";
}

int main()
{
BookList bookList;
bookList.length = 0;
bookList.books = new Book[MAXSIZE];
readFile(bookList);
int choice = 1;
while (choice)
{
menu();
cin >> choice;
switch (choice) {
case 1:{
readFile(bookList);
break;
}
case 2:{
string value;
cout << "请输入ID:";
cin >> value;
queryBook(bookList, value, 0, true);
break;
}
case 3:{
string value;
cout << "请输入书名:";
cin >> value;
queryBook(bookList, value, 1, true);
break;
}
case 4:{
addBook(bookList);
break;
}
case 5:{
string id;
cout << "请输入需要删除的书籍ID:";
cin >> id;
deleteBook(bookList, id);
break;
}
case 6:{
modifyBook(bookList);
break;
}
case 7:{
insertSort(bookList, 0);
break;
}
case 8:{
insertSort(bookList, 1);
break;
}
case 9:{
classify(bookList);
break;
}
case 10:{
printAll(bookList);
break;
}
case 11:{
save(bookList);
break;
}
case 12:{
extend(bookList);
break;
}
case 0:{
if (save(bookList))
return 0;
break;
}
default:{
cout << "请输入正确指令!" << endl;
break;
}


}
}
}

写在前面

功能模块一:文件读入

功能模块一:文件读入

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
void readFile(BookList & bookList){
string filename;
cout << "请输入需要读入的文件名:" << endl;
cin >> filename;
ifstream infile(filename);
if (!infile.is_open())
{
cout << "文件读入失败,请重试!" << endl;
return;
}

int length = bookList.length;
//数据预读入,可能会遇到空间不足问题
while (!infile.eof() && length < MAXSIZE)
{
infile >> bookList.books[length].id >> bookList.books[length].name >> bookList.books[length].press >> bookList.books[length].count
>> bookList.books[length].author >> bookList.books[length].price;
++length;
}
if (!infile.eof())
//无需删除元素,因为之后所有的操作都是根据bookList.length为索引,只要该值不变,内容就可理解为无变化
cout << "空间不足,读入失败!请先扩充空间!" << endl;
else
{
bookList.length = length;
cout << "文件读入成功" << endl;
}
infile.close();
}

采用ifstream读入二进制文本,系统开启时默认会动态分配MAXSIZE空间用来存储数据信息,如果分配空间不足以读入该文件,bookList.length并不会发生变化,可以简单理解为没有读入信息(注意length和bookList.length的区别)。当然,空间不足可以通过功能菜单12进行扩容。之后的所有操作都是以bookList.length为索引进行的,原理类似于bookList.length的top指针。那可能会问了,这不是浪费空间吗?其实在一开始就已经浪费了,因为系统开机就已经动态分配默认大小的空间了,当然这也是一个可以优化的点。这里是从bookList.length进行填加,并不会覆盖之前的数据。

文件读入运行截图

功能模块二:数据保存

功能模块二:数据保存

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
Status save(const BookList & bookList)
{
string filename;
cout << "请输入需要保存到的文件名:";
cin >> filename;
ofstream outfile(filename);
if (!outfile.is_open())
{
cout << "文件保存失败,是否退出(Y/N):";
char choice;
if ('Y' == choice || 'y' == choice)
return OK;
else return ERROR;
}
else
{
int length = bookList.length;
for (int i = 0; i < length; ++i)
outfile << bookList.books[i].id << " " << bookList.books[i].name << " " << bookList.books[i].press << " " << bookList.books[i].count << " "
<< " " << bookList.books[i].author << " " << bookList.books[i].price << endl;
cout << "文件保存成功!" << endl;
outfile.close();
return OK;
}
}

该模块处理了文件书写失败的情况,当无法打开文件时,会询问用户是否要强制退出,避免数据意外丢失。文件读取操作结束后一定要close

数据保存运行截图
数据保存运行截图

功能模块三:书籍查询

功能模块三:书籍查询

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
// flag = 0, 表示根据id查询;
// flag = 1, 表示根据图书名字查询;
// isNeedPrint, true表示需要打印信息;
int queryBook(const BookList & bookList, string value, int flag, bool isNeedPrint)
{
int length = bookList.length;
//id查询不可能重复
if (0 == flag)
{
for (int i = 0; i < length; i++)
if (value == bookList.books[i].id)
{
if (isNeedPrint)
printOne(bookList.books[i]);
return i;
}
if (isNeedPrint)
cout << "对不起,查无此书!" << endl;
return -1;
}
//书名查询可能重复
else if (1 == flag)
{
Book temp[bookList.length];
int count = 0;
for (int i = 0; i < length; i++)
if (value == bookList.books[i].name)
{
temp[count] = bookList.books[i];
count ++;
}

if (0 == count)
{
if (isNeedPrint)
cout << "对不起,查无此书!" << endl;
return -1;
}
else
{
if (isNeedPrint)
for (int i = 0; i < count; i++)
printOne(temp[i]);
return 1;
}
}
}

搜索功能用暴力实现,暂且没有算法优化。flag用来告知函数以哪种方式进行查询,0代表根据id查询,1代表根据书名查询。有个注意点,同名书籍可能存在,但id是唯一标识符。isNeedPrint如英文表示的一样,这样设计是为了方便添加书籍、删除书籍、修改书籍信息时调用该接口。同时该模块还有功能待扩充,仔细看可以注意到只写到else if,还可以根据其他关键字进行查询,这里就暂时不实现了。如果根据ID查询到该书籍,这直接返回元素下标,如果查不到,则返回-1。这里发现,return类型只支持返回int类型,如果根据其他关键字查询查找,返回值会有点问题,这个问题暂且搁置,不影响程序运行。

查询操作截图
查询操作截图
查询操作截图
查询操作截图
查询操作截图

功能模块四:信息打印

功能模块四:信息打印

功能模块五:删除书籍

功能模块五:删除书籍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void deleteBook(BookList & bookList, string id)
{

int position = queryBook(bookList, id, 0, false);
int length = bookList.length;
if (-1 != position)
{
for (int i = position; i < length - 1; i++)
bookList.books[i] = bookList.books[i + 1];
bookList.length --;
cout << "文件删除成功!" << endl;
}
else
cout << "对不起, 查无此书!" << endl;
}

在删除前会先根据ID进行查询,调用queryBook接口。之前设置isNeedPrint的作用就这样体现出来了。queryBook的返回值就可以直接定位需要删除的元素,直达病根。这里在删除前就不进行判空处理,因为queryBook函数会直接返回-1,不存在越界问题。

删除功能截图
删除功能截图

功能模块六:添加书籍

功能模块六:添加书籍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void addBook(BookList & bookList)
{
int length = bookList.length;
if (length >= MAXSIZE)
cout << "空间已满,请先开拓空间!" << endl;
else
{
cout << "请依次输入id、书名、出版社、数量、作者、价格" << endl;
cin >> bookList.books[length].id >> bookList.books[length].name >> bookList.books[length].press
>> bookList.books[length].count >> bookList.books[length].author >> bookList.books[length].price;
if (-1 != queryBook(bookList, bookList.books[length].id, 0, false))
{
cout << "信息添加失败,已存在同id书籍" << endl;
return;
}
bookList.length ++;
cout << "书籍添加成功!" << endl;
}
}

在添加书籍之前,会根据ID进行查询,避免数据重复,因为ID是唯一标识符,可以移至修改操作。运行之前还会判断空间是否已满。

添加操作截图

功能模块七:修改书籍信息

功能模块七:修改书籍信息

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
void modifyBook(BookList & bookList)
{
string id;
cout << "请输入需要修改的书籍id:";
cin >> id;
int position = queryBook(bookList, id , 0, false);
if (position == -1)
cout << "对不起,查无此书" <<endl;
else
{
char choice;
cout << "当前书籍名为:" << bookList.books[position].name << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新书名:";
cin >> bookList.books[position].name;

}

cout << "当前书籍出版社为:" << bookList.books[position].press << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新出版社:";
cin >> bookList.books[position].press;
}

cout << "当前书籍数量为:" << bookList.books[position].count << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新数量:";
cin >> bookList.books[position].count;
}

cout << "当前书籍作者为:" << bookList.books[position].author << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新作者:";
cin >> bookList.books[position].author;
}

cout << "当前书籍价格为:" << bookList.books[position].price << ",是否要修改(Y/N): ";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "请输入新价格:";
cin >> bookList.books[position].price;
}

cout << "信息修改完毕!" << endl;
cout << "修改后内容为:" << endl;
printOne(bookList.books[position]);
}
}

这里同样不需要判空处理,程序会根据提供的id定位到书籍,如果定位不到,则打印错误信息。如果定位到,会依次打印各项信息,并询问是否需要修改。这里同样可以优化,但先放着(因为每项询问可能会影响部分用户体现,可以试着开放两种修改方式,可供用户自由选择)。

修改操作截图

功能模块八:书籍排序

功能模块八:书籍排序

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
//flag = 0, 代表按照ID排序
//flag = 1,代表按照价格排序
void insertSort(BookList & bookList, int flag)
{
if (bookList.length == 0)
cout << "当前数据为空" << endl;
else if (bookList.length == 1)
return;
else
{
int length = bookList.length;
if (flag == 0)
{
int i, j;
for (i = 1; i < length; ++i)
if (bookList.books[i].id < bookList.books[i - 1].id)
{
Book temp = bookList.books[i];
for (j = i - 1; j >= 0 && temp.id < bookList.books[j].id; --j)
bookList.books[j + 1] = bookList.books[j];
bookList.books[j + 1] = temp;
}
cout << "已经按照ID升序完成排序!" << endl;
}

if (flag == 1)
{
int i, j;
for (i = 1; i < length; ++i)
if (bookList.books[i].price < bookList.books[i - 1].price)
{
Book temp = bookList.books[i];
for (j = i - 1; j >= 0 && temp.price < bookList.books[j].price; --j)
bookList.books[j + 1] = bookList.books[j];
bookList.books[j + 1] = temp;
}

cout << "已按照价格升序完成排序!" << endl;
}
}

}

flag用来告知函数接口按照何种关键字进行排序,此处也可以优化,比如增加关键字种类,选择升序或者降序。此处采用了性能较差的插入排序,有待后续优化。

排序操作截图
排序操作截图

功能模块九:按照类别打印

功能模块九:按照出版社类别打印

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
void classify(const BookList & bookList)
{
const int length = bookList.length;
if (bookList.length == 0)
cout << "当前数据为空" << endl;
else
{
int i ,j;
Book *books = new Book[length];
for (i = 0; i < length; ++i)
{
books[i] = bookList.books[i];
}

for (i = 1; i < length; ++i)
if (books[i].press < books[i - 1].press)
{
Book temp = books[i];
for (j = i - 1; j >= 0 && temp.press < books[j].press; --j)
books[j + 1] = books[j];
books[j + 1] = temp;
}

cout << books[0].press << ":" << endl;
printOne(books[0]);
for (i = 1; i < length; ++i)
{
if (books[i - 1].press != books[i].press)
cout << books[i].press << ":" << endl;
printOne(books[i]);
}
delete[] books;
}

}

该模块采用先将数据根据出版社进行排序,这样就便于按照出版社打印信息。有点需要注意,此处要将数据进行拷贝,避免对原始数据进行修改(你想修改也没法修改,因为我这里加了const,程序会报错)。处理结束后记得delete,按其他类别打印信息的原理一样,就不重复编写了。

分类打印截图

功能模块十:扩容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void extend(BookList & bookList)
{
MAXSIZE *= 2;
const int length = bookList.length;
Book *books = new Book[length];
for (int i = 0; i < length; ++i)
{
books[i] = bookList.books[i];
}
delete[] bookList.books;
bookList.books = new Book[MAXSIZE];
for (int i = 0; i < length; ++i)
{
bookList.books[i] = books[i];
}
delete[] books;
cout << "空间已扩大两倍" << endl;
}

这里按照2倍进行扩容,原因参考vector容器扩容策略,有兴趣的可以了解一下,这里不加赘述。

这里便于展示,我先将MAXSIZE修改为10再打开程序。
扩容操作截图
扩容操作截图
扩容操作截图

main函数呈现

main函数
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
int main()
{
BookList bookList;
bookList.length = 0;
bookList.books = new Book[MAXSIZE];
readFile(bookList);
int choice = 1;
while (choice)
{
menu();
cin >> choice;
switch (choice) {
case 1:{
readFile(bookList);
break;
}
case 2:{
string value;
cout << "请输入ID:";
cin >> value;
queryBook(bookList, value, 0, true);
break;
}
case 3:{
string value;
cout << "请输入书名:";
cin >> value;
queryBook(bookList, value, 1, true);
break;
}
case 4:{
addBook(bookList);
break;
}
case 5:{
string id;
cout << "请输入需要删除的书籍ID:";
cin >> id;
deleteBook(bookList, id);
break;
}
case 6:{
modifyBook(bookList);
break;
}
case 7:{
insertSort(bookList, 0);
break;
}
case 8:{
insertSort(bookList, 1);
break;
}
case 9:{
classify(bookList);
break;
}
case 10:{
printAll(bookList);
break;
}
case 11:{
save(bookList);
break;
}
case 12:{
extend(bookList);
break;
}
case 0:{
if (save(bookList))
return 0;
break;
}
default:{
cout << "请输入正确指令!" << endl;
break;
}


}
}
}