一、系统功能模块图

二、代码
//************************图书管理系统*************
#include<iostream>
#include<string.h>
#include <cassert>
#include <iomanip>
#include<fstream>
#include<stdlib.h>
#include<conio.h>
#include<malloc.h>
#include <bits/stdc++.h>
#include <cstring>
#define maxsize 30
using namespace std;
/*typedef struct student
{
int num;
struct student *next;
}student;
struct student
{
int num;
struct student *next;
};
这两种定义有什么区别?
第二个struct student是定义了一个student结构体,这个明白吧。
第一个是用typedef把struct student这个结构体类型名字重新定义为student,
也就是说struct student和student表示同一个事物,
都是一个类型的标识符,比如 typedef int zhengshu;
就是你把整型int重命名为zhengshu,下面定义:int i; 和 zhengshu i;
两句就是等价的了 */
typedef struct { //定义结构体:book
int num; //书号
char name[maxsize]; //书名
char writer[maxsize]; //作者
float price; //价格
char shename[maxsize]; //出版社
}book;
typedef struct{ //定义链表结构体:linklist
book *data; //数据存储域
int length; //长度域
}linklist;
void init(linklist &L) //构造空链表
{L.data=(book*)malloc(maxsize*sizeof(book));
L.length=0;} //开创空间后再设置长度为0
void printflist(linklist &L) //输出
{ int i;
for(i=0;i<L.length;i++)
{ cout<<L.data[i].num<<" 《"<<L.data[i].name<<"》 ¥"<<setiosflags(ios::fixed)<<setprecision(2)<<L.data[i].price;
cout<<" 作者:"<<L.data[i].writer<<" 出版社:"<<L.data[i].shename;
cout<<"\n";}}
#define Status bool
Status deletelist(linklist &L,int i) //删除
{ int k;
if(i<1||i>L.length)
return false;
for(k=i;k<=L.length-1;k++)
{L.data[k-1]=L.data[k];}
L.length--;
cout<<" 删除已完成\n";
return true;}//相当于如下
/*bool deletelist(linklist &L,int i) //删除
{ int k;
if(i<1||i>L.length)
return false;
for(k=i;k<=L.length;k++)
{L.data[k-1]=L.data[k];}
L.length--;
cout<<" 删除已完成\n";
return true;}*/
bool DestroyList(linklist &L){
if(0==L.length) return false;
free(L.data);
L.data = NULL;
L.length = 0;
return true;
}
bool quandelete(linklist &L,int i) //删除所有数据
{ int k;
if(i<0||i>L.length-1) //指定元素位置过于奇特
return false;
cout<<" 已删除所有数据\n";
for(k=L.length;k>0;k--)
{L.data[k-1]=L.data[k]; //将后面元素依次前移
L.length--;}
return true;
}
void shuchangemoney(linklist &L) //通过书号修改价格
{ int i,f;float g;
cout<<" 请输入需要修改的价格的书号:";
cin>>f;
cout<<" 请输入您想要修改的价格:";
cin>>g;
for(i=0;i<=L.length;i++)
{ if(i==f)
L.data[i-1].price=g;}
cout<<"已完成价格修改\n";
printflist(L);}
void change(linklist &L,book s) //通过书号修改整本书
{ int i,q;
cout<<"请输入需要修改的书的书号:";
cin>>q;
cout<<"请分别输入您想要修改这本书的书号、价格、作者、出版社:";
cin>>s.name>>s.price>>s.writer>>s.shename;
for(i=1;i<=L.length;i++)
{ if(i==q)
{ L.data[i-1]=s;
L.data[i-1].num=q;}}
cout<<"已完成修改\n";
printflist(L);}
void chanum(linklist &L,int i) //根据书号查找信息
{ int num;
cout<<"请输入需要查找图书的书号:";
cin>>num;
cout<<"查找结果:\n";
for(i=0;i<L.length;i++)
{ if(num==i+1)
{
cout<<L.data[i].num<<" 《"<<L.data[i].name<<"》 ¥"<<setiosflags(ios::fixed)<<setprecision(2)<<L.data[i].price;
cout<<" 作者:"<<L.data[i].writer<<" 出版社:"<<L.data[i].shename;
cout<<"\n";}}}
void chaname(linklist &L,int i) //根据书名查找信息
{ int n;
char bookname[20];
int num=L.length;
cout<<"请输入需要查找图书的书名:";
cin>>bookname;
for(i=0;i<num;i++)
{ if(strcmp(L.data[i].name,bookname)==0)
{ n++;
cout<<"查找成功! 该图书的信息为:\n"<<endl;
cout<<L.data[i].num<<" 《"<<L.data[i].name<<"》 ¥"<<setiosflags(ios::fixed)<<setprecision(2)<<L.data[i].price;
cout<<" 作者:"<<L.data[i].writer<<" 出版社:"<<L.data[i].shename;
cout<<"\n";}}
if(n==0)
cout<<"查找失败!\n"<<endl;}
void chawriter(linklist &L,int i) //根据作者查找信息
{ int n;
char bookname[20];
int num=L.length;
cout<<"请输入需要查找图书的作者:";
cin>>bookname;
cout<<"查找结果\n";
for(i=0;i<num;i++)
{if(strcmp(L.data[i].writer,bookname)==0)
{n++;
cout<<L.data[i].num<<" 《"<<L.data[i].name<<"》 ¥"<<setiosflags(ios::fixed)<<setprecision(2)<<L.data[i].price;
cout<<" 作者:"<<L.data[i].writer<<" 出版社:"<<L.data[i].shename;
cout<<"\n";}}
if(n==0)
cout<<"查找失败!\n"<<endl;}
void chashename(linklist &L,int i) //根据书名查找信息
{ int n;
char chashename[20];
cout<<"请输入需要查找图书的出版社:";
cin>>chashename;
int num=L.length;
for(i=0;i<num;i++)
{if(strcmp(L.data[i].name,chashename)==0)
{n++;
cout<<"查找成功! 该图书的信息为:\n"<<endl;
cout<<L.data[i].num<<" 《"<<L.data[i].name<<"》 ¥"<<setiosflags(ios::fixed)<<setprecision(2)<<L.data[i].price;
cout<<" 作者:"<<L.data[i].writer<<" 出版社:"<<L.data[i].shename;
cout<<"\n";}}
if(n==0)
cout<<"查找失败!\n"<<endl;}
bool chamaxprice(linklist &L,int i) //查出最贵的书的信息
{ if(L.length=0)
{return false;}
i=1;
int index=0;
float exp=L.data[0].price;
while(i<L.length)
{if(L.data[i].price>exp)
{exp=L.data[i].price;
index=i;}}
cout<<"最贵的图书信息如下:";
cout<<L.data[index].num<<" 《"<<L.data[index].name;
cout<<"》 ¥"<<L.data[index].price<<" 作者:"<<L.data[index].writer<<" 出版时间:"<<L.data[index].shename;}
void pricepaixu(linklist &L,int j) //价格排序
{ int i;
int n=L.length;
book temp;
for(i=1;i<n;i++)
{ for(j=0;j<n-i;j++)
{ if(L.data[j].price>L.data[j+1].price)
{temp=L.data[j];
L.data[j]=L.data[j+1];
L.data[j+1]=temp;}}}
cout<<"已完成排序:\n";
printflist(L);}
void namepaixu(linklist &L,int j) //书名排序
{ int i;
int n=L.length;
book t;
for(i=0;i<n-1;i++)
{ for(j=0;j<n-i-1;j++)
{ if(strcmp(L.data[j].name,L.data[j+1].name)>0)
{t=L.data[j];
L.data[j]=L.data[j+1];
L.data[j+1]=t;}}}
cout<<"已完成排序:\n";
printflist(L);}
void blacktowhite(linklist &L) //逆置
{ int i,j;
int n=L.length;
book temp;
for(i=1;i<n;i++)
{ for(j=0;j<n-i;j++)
{ if(L.data[j].num<L.data[j+1].num)
{temp=L.data[j];
L.data[j]=L.data[j+1];
L.data[j+1]=temp;}}}
/* linklist S;
init(S);
int i,n=L.length;
for(i=0;i<n;i++)
{S.data[i]=L.data[i];}
for(i=0;i<n;i++)
{L.data[i]=S.data[n-i-1];
deletelist(S,n-i);
L.length++;}*/
cout<<"逆置成功\n";
}
bool insert(linklist &L,int i,book &e) //插入
{ cout<<"分别输入书名、价格、作者、出版社:\n";
cin>>e.name>>e.price>>e.writer>>e.shename;
cout<<"想插入到第几个位置:";
cin>>e.num;
int j;
i=e.num;
if(i<1||i>L.length+1)//位置不合法,返回失败
{return false;}
if(L.length==maxsize)
{return false;}
cout<<"插入完成\n";
for(j=L.length-1;j>=i-1;j--)
{L.data[j+1].num=L.data[j].num+1;//i后所有元素在顺序表上向后移动一位L.data[i].num=e.num;//将e放入第i位
strcpy(L.data[j+1].name,L.data[j].name);
L.data[j+1].price=L.data[j].price;
strcpy(L.data[j+1].writer,L.data[j].writer);
strcpy(L.data[j+1].shename,L.data[j].shename);}
L.data [i-1]=e;
++L.length;
return true; }
bool input(linklist &L) //创建
{ char i;
int y;
int j,k;
if(L.length>maxsize)
{cout<<"库存已满\n";return false;}
else
{for(;;y++){
L.data[L.length].num=L.length+1;
cout<<"输入信息";
cout<<L.data[L.length].num<<"\n";
cout<<"输入书籍名称:";cin>>L.data[L.length].name;
cout<<"输入价格:";cin>>L.data[L.length].price;
cout<<"输入作者:";cin>>L.data[L.length].writer;
cout<<"输入出版社:";cin>>L.data[L.length].shename;
L.length++;
cout<<"结束输入?\n 是(Y/y) 否(N)\n";
cin>>i;
if(i=='y'||i=='Y')
{break;}
if(L.length>maxsize)
{ cout<<"库存已达上限!\n";
return false;
}}}return true;}
void quchong(linklist &L) //去重
{ int i,j;
for(i=0;i<L.length;i++)
{ for(j=i+1;j<L.length;j++)
{ if(strcmp(L.data[i].name,L.data[j].name)==0)
{ deletelist(L,j+1);
j--;}} }
cout << "去重完成!\n" << endl << endl;}
int writertongji(linklist &L) //一个作者有多少本书
{ int n=0,i;
char zuozhe[maxsize];
cout<<" 请输入作者名:\n";
cin>>zuozhe;
for(i=0;i<L.length;i++){
if(strcmp(L.data[i].writer,zuozhe)==0)
n++;}
cout<<"作者的图书总量:"<<n<<"\n";}
int shenametongji(linklist &L) //出版社统计
{ int i,n=0;
char chubanshe[maxsize];
cout<<" 请输入出版社名:";
cin>>chubanshe;
for(i=0;i<L.length;i++){
if(strcmp(chubanshe,L.data[i].shename)==0){
n++;}}
cout<<"出版社图书总量:"<<n<<"\n";}
void meau() //主菜单
{ cout<<"-----------------------------------------------------\n";
cout<<"* *图书管理系统* *\n";
cout<<"=====================================================\n";
cout<<"* 1.创建 *\n";
cout<<"* 2.输出 *\n";
cout<<"* 3.修改 *\n";
cout<<"* 4.插入 *\n";
cout<<"* 5.删除 *\n";
cout<<"* 6.删除所有数据 *\n";
cout<<"* 7.去重 *\n";
cout<<"* 8.查找 *\n";
cout<<"* 9.排序 *\n";
cout<<"* 10.统计 *\n";
cout<<"* 11.逆置 *\n";
cout<<"* 0.退出 *\n";
cout<<"=====================================================\n";
cout<<" 请输入选择:";}
void chazhao(linklist &L) //查找
{ int q;
cout<<"*********************\n";
cout<<"* 查找 *\n";
cout<<"* 1.书号查找 *\n";
cout<<"* 2.书名查找 *\n";
cout<<"* 3.作者查找 *\n";
cout<<"* 4.出版社查找 *\n";
cout<<"* 5.最贵书查找 *\n";
cout<<"*********************\n";
cout<<" 请输入查找选择:";
cin>>q;
switch(q){
int e;
case 1:chanum(L,e);break;
case 2:chaname(L,e);break;
case 3:chawriter(L,e);break;
case 4:chashename(L,e);break;
case 5:chamaxprice(L,e);break;}}
void xiugai(linklist &L)
{ int f;
book t;
cout<<"****************************************************\n";
cout<<"* 修改 *\n";
cout<<"* 1.通过书号修改价格 *\n";
cout<<"* 2.通过书号修改书号、价格、作者、出版社: *\n";
cout<<"****************************************************\n";
cout<<" 请输入排序选择:";
cin>>f;
switch(f){
case 1:shuchangemoney(L);break;
case 2:change(L,t);break;}}
void paixu(linklist &L) //从小到大排序
{ int w;
cout<<"*************************\n";
cout<<"* 排序 *\n";
cout<<"* 1.价格排序 *\n";
cout<<"* 2.书名排序 *\n";
cout<<"*************************\n";
cout<<" 请输入排序选择:";
cin>>w;
switch(w){
int y;
char a;
case 1: pricepaixu(L,y);break;
case 2:namepaixu(L,y); break;}}
void tongji (linklist &L) //统计
{ int d;
cout<<"**************************\n";
cout<<"* 统计 *\n";
cout<<"* 1.作者的图书总量 *\n";
cout<<"* 2.出版社的图书总量 *\n";
cout<<"* 3.图书总量 *\n";
cout<<"**************************\n";
cout<<" 请输入统计选择: ";
cin>>d;
switch(d)
{
case 1:writertongji(L);break;
case 2:shenametongji(L);break;
case 3:cout<<"图书总量:"<<L.length<<"\n";break;}}
int main() //主函数
{ linklist L;
book e;
init(L);
int choice;
do{ char a;
meau();
cin>>choice;
switch(choice){
case 1:init(L); input(L); break; //创建及维护
case 2:printflist(L);cout<<"请按b/B键退出\n"; cin>>a; //输出
if(a=='b'||a=='B'){break;}
case 3:xiugai(L); cout<<"请按b/B键退出\n"; cin>>a; //修改
if(a=='b'||a=='B')break;
case 4: insert(L,e.num,e); //插入
cout<<"请按b/B键退出\n"; cin>>a;
if(a=='b'||a=='B'){ break;}
case 5:printflist(L); //删除
cout<<"输入需要删除数据的编号:";
int z; cin>>z;
if(deletelist(L,z)==1)
cout<<"删除成功!\n";
else
cout<<"数据非法!!!\n";cout<<"请按b/B键退出\n"; cin>>a;
if(a=='b'||a=='B')break;
case 6:int n;quandelete(L,n); cout<<"按b/B键退出\n"; cin>>a; //删除所有数据
if(a=='b'||a=='B')break;
case 7:quchong(L); cout<<"按b/B键退出\n"; cin>>a; //去重
if(a=='b'||a=='B')break;
case 8:chazhao(L); cout<<"请按b/B键退出\n"; cin>>a; //查找
if(a=='b'||a=='B')break;
case 9:paixu(L); cout<<"按b/B键退出\n"; cin>>a; //排序
if(a=='b'||a=='B')break;
case 10:tongji(L); cout<<"按b/B键退出\n"; cin>>a; //统计
if(a=='b'||a=='B')break;
case 11:blacktowhite(L); cout<<"按b/B键退出\n"; cin>>a; //逆置
if(a=='b'||a=='B')break;}
if(choice>11)cout<<" 输入错误,请重新输入选择:\n"; //重新输入
}while(choice!=0);
return 0; }
/* while(n)
{ Menu();
scanf("%d",&choice);
switch(choice)
{
case 1:
input(score,50);
break;
case 2:
output(score,50);
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 0:
n=0;break;
default:
printf("输入有误,请输入0-7进行选择!");
}
}
switch (num)
{
//case 1:
// input_score(score);//成绩的录入函数
// break;a
//case 2:
// output_score(score);//成绩的打印函数
// break;
//case 3:
// change_score(score);//成绩的修改函数
// break;
//case 4:
// count_score(score);//统计各分数段人数的函数
// break;
//case 5:
// average_score(score);//统计平均分的函数
// break;
//case 6:
// fail_score(score);//统计不及格学生人数的函数
// break;
case 0:
num = 0;//跳出循环
break;
default:
printf("输入错误,请输入有效数字。");
}
} while (num);*/
/*#include <iostream>
#include <stdlib.h>
using namespace std;
#define InitSize 64 // 默认的最大长度
typedef struct
{
int *data; // 动态分配数据的指针
int maxSize; // 顺序表的最大容量
int length; // 顺序表的当前长度
} SeqList;
// 初始化
void initList(SeqList &l)
{
// C语言版本:使用malloc函数申请一片连续的存储空间
// l.data = (int *)malloc(InitSize * sizeof(int));
// C++版本
l.data = new int[InitSize];
// 下面相同
l.length = 0;
l.maxSize = InitSize;
}
// 增加动态数组的长度
void increaseSize(SeqList &l, int len)
{
int *p = l.data;
// l.data = (int *)malloc((l.maxSize + len) * sizeof(int));
l.data = new int[l.maxSize + len];
for (int i = 0; i < l.maxSize; i++)
{
l.data[i] = p[i]; // 将数据复制到新区域
}
l.maxSize = l.maxSize + len; // 顺序表最大长度增加len
// free(p);
delete[] p; // 释放原来的内存空间
}
int main()
{
SeqList l; // 声明一个顺序表
initList(l); // 初始化顺序表
// 增删查改
cout << "初始顺序表的长度: " << l.length << endl;
cout << "初始顺序表的最大长度: " << l.maxSize << endl;
increaseSize(l, 5);
cout << "修改后顺序表的最大长度: " << l.maxSize << endl;
return 0;
}
*/
/*在C语言中,动态分配内存用 malloc() 函数,释放内存用 free() 函数。
// 申请空间
l.data = (int *)malloc((l.maxSize + len) * sizeof(int));
// 释放空间
free(p);
1
2
3
4
在C++中,这两个函数仍然可以使用,但是C++又新增了两个关键字,new 和 delete:
new 用来动态分配内存,delete 用来释放内存。
// 申请空间
l.data = new int[l.maxSize]; // new 操作符会根据后面的数据类型来推断所需空间的大小。
// 释放空间
delete[] p; // 用 new[] 分配的内存需要用 delete[] 释放,它们是一一对应的。
1
2
3
4
和 malloc() 一样,new 也是在堆区分配内存,必须手动释放,否则只能等到程序运行结束由操作系统回收。
为了避免内存泄露,通常 new 和 delete、new[] 和 delete[] 操作符应该成对出现,并且不要和C语言中 malloc()、free() 一起混用。
*/
三、结果截图
(1)菜单结构截图

(2)图书信息创建及维护

(3)图书的输出

(4)图书修改


(5)图书插入


(6)图书删除


(7)图书去重


(8)图书查找





(9)图书排序


(10)图书统计


