C++ 面向对象技术与编程课程设计——图书信息管理系统
目录
前言
先来一张效果图
一、基本要求
图书信息管理系统能实现以下功能:系统以菜单方式工作,图书信息录入功能(图书信息用文件保存) ;图书信息包括:登录号、书名、作者名、分类号、出版单位、出版时间、 价格;图书信息浏览功能(输出所有图书信息);查询和排序功能:按书名查询(显示所有同名的书),按作者名查询(所有该作者的书); 图书信息的删除,插入与修改。输入其他任意字符(错误输入)会显示其错误输入的输出结果。
二、流程图
界面显示菜单,通过用户的输入,switch进行判断调用相应的方法,显示相应的信息,结束这个功能后,界面显示询问:“继续吗?”,用户输入,若是取消,则退出系统;若是确定,则刷新页面,显示菜单。
三、代码
1.类的创建
一共创建了两个类。book类存放图书的各种信息,library类存放每本图书的对象,单链表指针(即library类的对象的地址)和各种功能。
class book
{
public:
char name[100];
char num[100];
char tel[100];
char name1[100];
char time[100];
char cla[100];
char adress[100];
};
class library
{
public:
book data;//对象
library *next;//单链表指针
void londecreat(library L, int n);//录入信息
void display();//显示信息
void sort();//排序信息
void findname(char* arr);//查找作者名
void findbook(char* arr);//查找图书名
void delete1(library &L, char* arr);//删除信息
void modify(library &L, char* arr, char* arr1, char* arr2,
char* arr3, char* arr4, char* arr5, char* arr6, char* arr7);//修改信息
void insert(library &L, char* arr, char* arr2, char* arr3,
char* arr4, char* arr5, char* arr6,char* arr7,char* arr8);//插入信息
};
2.录入图书信息
实参为library类的对象L和录入n本图书,创建n个library类的对象指针,对对象指针进行内存分配,储存相应的图书信息,完成单链表的创建,写入文件。
void library::londecreat(library L, int n)
{
L.next = NULL;
library *p, *q;
q = &L; //地址相同
int i = 0;
cout << "请您依次输入登录号,图书名,作者名,分类号,出版单位,出版时间,价格" << endl;
for (i = 0; i < n; i++)
{
if(i>0)
{
cout<<"请输入第"<<i+1<<"本书"<<endl;
}
p=new library();
cin >> p->data.name;
cin >> p->data.num;
cin >> p->data.tel;
cin >> p->data.cla;
cin >> p->data.name1;
cin >> p->data.time;
cin >> p->data.adress;
p->next = NULL;
q->next = p; //等于用这条语句:q->next = p;
q = p;
}
ofstream ofs;
ofs.open("text.txt", ios::out);
library *S;
S = L.next;
while (S)
{
ofs << S->data.name << " " << S->data.num << " " << S->data.tel << " " << S->data.cla << " " << S->data.name1 << " " << S->data.time << " " << S->data.adress << " " << endl;
S = S->next;
}
ofs.close();
}
创建单链表图如下:
3.删除图书信息
删除图书的信息也逻辑也基本一样,重新分配地址,完成单链表,再将要删除对象的内存释放,这里用的free函数,再写入文件。注意:这里的实参L必须是地址,要不然修改的地址只在方法中有效。
void library::delete1(library &L, char* arr)
{
library *S;
S = L.next;
while(S)
{
S = S->next;
}
char a[100], b[100];
int i = 0, j = 0, count = 0;
strcpy(a, arr);
while (*arr != '\0')
{
count++;
arr++;
}
library *p, *q, *r;
q = &L;
p = L.next;
while (p != NULL)
{
strcpy(b, p->data.name);
i = 0, j = 0;
while (a[i] == b[j] && a[i] != '\0' && b[j] != '\0')
{
i++;
j++;
}
if (i == count)
{
r = p;
while (q)
{
while (q->next == r)
{
q->next = q->next->next;
free(r);
cout << "删除图书信息成功!" << endl;
ofstream ofs;
ofs.open("text.txt", ios::out);
library *S;
S = L.next;
while (S)
{
ofs << S->data.name << " " << S->data.num << " " << S->data.tel << " " << S->data.cla << " "<< S->data.name1 << " " << S->data.time << " " << S->data.adress << " " << endl;
S = S->next;
}
ofs.close();
return;
}
q = q->next;
}
}
p = p->next;
}
cout<<"查无此书,删除失败"<<endl;
}
单链表图如下:
4.插入图书信息
插入图书信息的逻辑也是一样的,新增加一个对象指针s,赋予内存,将单链表重新分配,再写入文件。
void library::insert(library &L, char* arr, char* arr2, char* arr3, char* arr4, char* arr5, char* arr6,char* arr7,char* arr8)
{
library *p, *q, *s;
char a[100], b[100];
int count = 0, i = 0, j = 0;
s = new library();
strcpy(s->data.name, arr2);
strcpy(s->data.num, arr3);
strcpy(s->data.tel, arr4);
strcpy(s->data.cla, arr5);
strcpy(s->data.name1, arr6);
strcpy(s->data.time, arr7);
strcpy(s->data.adress, arr8);
strcpy(a, arr);
while (*arr != '\0')
{
count++;
arr++;
}
q = &L;
p = L.next;
while (p != NULL)
{
strcpy(b, p->data.name);
i = 0, j = 0;
while (a[i] == b[j] && a[i] != '\0' && b[j] != '\0')
{
i++;
j++;
}
if (i == count)
{
while (q)
{
while (q->next == p)
{
q->next = s;
s->next = p;
cout << "插入成功" << endl;
ofstream ofs;
ofs.open("text.txt", ios::out);
library *S;
S = L.next;
while (S)
{
ofs << S->data.name << " " << S->data.num << " " << S->data.tel << " " << S->data.cla << " " << S->data.name1 << " " << S->data.time << " " << S->data.adress << " " << endl;
S = S->next;
}
ofs.close();
S = L.next;
return;
}
q = q->next;
}
}
p = p->next;
}
cout<<"查无此书,插入失败"<<endl;
}
单链表图如下:
5.查找图书信息
将文件中信息输出到数组里,与使用者输入的信息对比,用strcmp函数(比较两个字符数组的大小)。一旦匹配成功,便输出该图书信息,因为图书信息是顺序输出,而要查找的图书书名的图书信息(每本书的信息有七个)在第二个,那么就要创建一个数组保存第一个图书信息(图书编号)。
void library::findbook(char* arr)
{
char a[100];
strcpy(a, arr);
ifstream ifs;
ifs.open("text.txt", ios::in);
char buf[10000] = { 0 };
string buf1;
int i = 0,find=0;
while (ifs >> buf)
{
if (i == 5)
{
cout << buf << " "<<endl;
i=0;
find=1;
}
if (i >= 1&&i<5)
{
cout << buf << " ";
i++;
}
int n = strcmp(a, buf); //比较两个字符串的大小
if(n!=0)
{
buf1=buf;
}
if (n == 0)
{
cout << buf1 << " ";
cout << buf << " ";
i++;
}
}
ifs.close();
if(find==0)
{
cout<<"查无此书"<<endl;
}
}
6.整体代码
在刚开始运行时内存中是没有单链表的,所以需要在主函数中加一个创建单链表的代码,跟录入图书信息的方法一样,就是把键盘输入改成文件输入。
#include<iostream>
#include<stdio.h>
#include<string>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<fstream>
#include <windows.h>
using namespace std;
class book
{
public:
char name[100];
char num[100];
char tel[100];
char name1[100];
char time[100];
char cla[100];
char adress[100];
};
class library
{
public:
book data;//对象
library *next;//单链表指针
void londecreat(library L, int n);//录入信息
void display();//显示信息
void sort();//排序信息
void findname(char* arr);//查找作者名
void findbook(char* arr);//查找图书名
void delete1(library &L, char* arr);//删除信息
void modify(library &L, char* arr, char* arr1, char* arr2,
char* arr3, char* arr4, char* arr5, char* arr6, char* arr7);//修改信息
void insert(library &L, char* arr, char* arr2, char* arr3,
char* arr4, char* arr5, char* arr6,char* arr7,char* arr8);//插入信息
};
void color(short x)//改变颜色
{
if(x>=0 && x<=15)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
else
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
void library::londecreat(library L, int n)
{
L.next = NULL;
library *p, *q;
q = &L; //地址相同
int i = 0;
cout << "请您依次输入登录号,图书名,作者名,分类号,出版单位,出版时间,价格" << endl;
for (i = 0; i < n; i++)
{
if(i>0)
{
cout<<"请输入第"<<i+1<<"本书"<<endl;
}
p=new library();
cin >> p->data.name;
cin >> p->data.num;
cin >> p->data.tel;
cin >> p->data.cla;
cin >> p->data.name1;
cin >> p->data.time;
cin >> p->data.adress;
p->next = NULL;
q->next = p; //等于用这条语句:q->next = p;
q = p;
}
ofstream ofs;
ofs.open("text.txt", ios::out);
library *S;
S = L.next;
while (S)
{
ofs << S->data.name << " " << S->data.num << " " << S->data.tel << " " << S->data.cla << " " << S->data.name1 << " " << S->data.time << " " << S->data.adress << " " << endl;
S = S->next;
}
ofs.close();
}
void library::display()
{
ifstream ifs;
ifs.open("text.txt", ios::in);
char buf[10000] = { 0 };
int i = 0;
cout << "下面是您录入的信息" << endl;
while (ifs >> buf)
{
if (i % 7 == 0)
{
cout << endl;
}
cout << buf << " ";
i++;
}
ifs.close();
}
void library::sort()
{
fstream ifs;
ifs.open("text.txt", ios::in);
char buf[10000] = { 0 };
double clanum[100]; //储存分类号
int i = 0,cla=0,a=1;
while (ifs >> buf)
{
if (i % 7 == 3)
{
int x=0;
while(buf[x]!='\0')
{
x++;
}
x--;
while(x>=0)
{
clanum[cla]=clanum[cla]+(buf[x]-'0')*a;
x--;
a=a*10;
if(x==-1)
{
cla++;
}
}
}
i++;
a=1;
}
ifs.close();
int f=1;
while (f==1)
{
// 判断分类号的大小,找到最大的号记下位置并删除
int big=0,k=1,t=1;
while(t==1)
{
if(clanum[big]>=clanum[k])
{
k++;
}
else
{
big=k;
}
if(clanum[k]==0)
{
t=0;
clanum[big]=-1;
cla--;
}
}
ifs.open("text.txt", ios::in);
for(i=0;i<(big*7+7);i++)
{
ifs>>buf;
if(i>=big*7)
{
cout << buf << " ";
}
}
ifs.close();
cout<<endl;
if(cla==0)
{
f=0;
}
}
}
void library::findname(char* arr)
{
char a[100];
strcpy(a, arr);
ifstream ifs;
ifs.open("text.txt", ios::in);
char buf[10000] = { 0 };
string buf1;
string buf2;
int i = 0,find=0;
while (ifs >> buf)
{
if (i == 5)
{
cout << buf << " "<<endl;
i=0;
find=1;
}
if (i >= 1&&i<5)
{
cout << buf << " ";
i++;
}
int n = strcmp(a, buf); //比较两个字符串的大小
if(n!=0)
{
buf2=buf1;
buf1=buf;
}
if (n == 0)
{
cout << buf2 << " ";
cout << buf1 << " ";
cout << buf << " ";
i++;
}
}
ifs.close();
if(find==0)
{
cout<<"查无此书"<<endl;
}
}
void library::findbook(char* arr)
{
char a[100];
strcpy(a, arr);
ifstream ifs;
ifs.open("text.txt", ios::in);
char buf[10000] = { 0 };
string buf1;
int i = 0,find=0;
while (ifs >> buf)
{
if (i == 5)
{
cout << buf << " "<<endl;
i=0;
find=1;
}
if (i >= 1&&i<5)
{
cout << buf << " ";
i++;
}
int n = strcmp(a, buf); //比较两个字符串的大小
if(n!=0)
{
buf1=buf;
}
if (n == 0)
{
cout << buf1 << " ";
cout << buf << " ";
i++;
}
}
ifs.close();
if(find==0)
{
cout<<"查无此书"<<endl;
}
}
void library::delete1(library &L, char* arr)
{
library *S;
S = L.next;
while(S)
{
S = S->next;
}
char a[100], b[100];
int i = 0, j = 0, count = 0;
strcpy(a, arr);
while (*arr != '\0')
{
count++;
arr++;
}
library *p, *q, *r;
q = &L;
p = L.next;
while (p != NULL)
{
strcpy(b, p->data.name);
i = 0, j = 0;
while (a[i] == b[j] && a[i] != '\0' && b[j] != '\0')
{
i++;
j++;
}
if (i == count)
{
r = p;
while (q)
{
while (q->next == r)
{
q->next = q->next->next;
free(r);
cout << "删除图书信息成功!" << endl;
ofstream ofs;
ofs.open("text.txt", ios::out);
library *S;
S = L.next;
while (S)
{
ofs << S->data.name << " " << S->data.num << " " << S->data.tel << " " << S->data.cla << " "<< S->data.name1 << " " << S->data.time << " " << S->data.adress << " " << endl;
S = S->next;
}
ofs.close();
return;
}
q = q->next;
}
}
p = p->next;
}
cout<<"查无此书,删除失败"<<endl;
}
void library::insert(library &L, char* arr, char* arr2, char* arr3, char* arr4, char* arr5, char* arr6,char* arr7,char* arr8)
{
library *p, *q, *s;
char a[100], b[100];
int count = 0, i = 0, j = 0;
s = new library();
strcpy(s->data.name, arr2);
strcpy(s->data.num, arr3);
strcpy(s->data.tel, arr4);
strcpy(s->data.cla, arr5);
strcpy(s->data.name1, arr6);
strcpy(s->data.time, arr7);
strcpy(s->data.adress, arr8);
strcpy(a, arr);
while (*arr != '\0')
{
count++;
arr++;
}
q = &L;
p = L.next;
while (p != NULL)
{
strcpy(b, p->data.name);
i = 0, j = 0;
while (a[i] == b[j] && a[i] != '\0' && b[j] != '\0')
{
i++;
j++;
}
if (i == count)
{
while (q)
{
while (q->next == p)
{
q->next = s;
s->next = p;
cout << "插入成功" << endl;
ofstream ofs;
ofs.open("text.txt", ios::out);
library *S;
S = L.next;
while (S)
{
ofs << S->data.name << " " << S->data.num << " " << S->data.tel << " " << S->data.cla << " " << S->data.name1 << " " << S->data.time << " " << S->data.adress << " " << endl;
S = S->next;
}
ofs.close();
S = L.next;
return;
}
q = q->next;
}
}
p = p->next;
}
cout<<"查无此书,插入失败"<<endl;
}
void library::modify(library &L, char* arr, char* arr1, char* arr2, char* arr3, char* arr4, char* arr5, char* arr6, char* arr7)
{
char a[100], b[100];
strcpy(a, arr);
library *p;
int count = 0, i = 0, j = 0;
while (*arr != '\0')
{
count++;
arr++;
}
p = L.next;
while (p)
{
strcpy(b, p->data.name);
i = 0, j = 0;
while (a[i] == b[j] && a[i] != '\0' && b[j] != '\0')
{
i++;
j++;
}
if (i == count)
{
strcpy(p->data.name, arr1);
strcpy(p->data.num, arr2);
strcpy(p->data.tel, arr3);
strcpy(p->data.cla, arr4);
strcpy(p->data.name1, arr5);
strcpy(p->data.time, arr6);
strcpy(p->data.adress, arr7);
cout << "修改成功" << endl;
ofstream ofs;
ofs.open("text.txt", ios::out);
library *S;
S = L.next;
while (S)
{
ofs << S->data.name << " " << S->data.num << " " << S->data.tel << " " << S->data.cla << " " << S->data.name1 << " " << S->data.time << " " << S->data.adress << " " << endl;
S = S->next;
}
ofs.close();
return;
}
p = p->next;
}
cout<<"查无此书,修改失败"<<endl;
}
void menu()//输出菜单
{
color(10);
cout << "\t\t\t****************************************************************" << endl;
cout << "\t\t\t**********************欢迎光临图书管理系统**********************" << endl;
cout << "\t\t\t****************** ******************" << endl;
cout << "\t\t\t****************** 输入0 退出程序 ******************" << endl;
cout << "\t\t\t****************** 输入1 录入信息 ******************" << endl;
cout << "\t\t\t****************** 输入2 陈列信息 ******************" << endl;
cout << "\t\t\t****************** 输入3 按作者名查找 ******************" << endl;
cout << "\t\t\t****************** 输入4 按书名查找 ******************" << endl;
cout << "\t\t\t****************** 输入5 删除信息 ******************" << endl;
cout << "\t\t\t****************** 输入6 插入信息 ******************" << endl;
cout << "\t\t\t****************** 输入7 修改信息 ******************" << endl;
cout << "\t\t\t****************** 输入8 按分类号排序 ******************" << endl;
cout << "\t\t\t****************** ******************" << endl;
cout << "\t\t\t****************************************************************" << endl;
}
int main()
{
library L;
char arr[100], arr2[100], arr4[100], arr5[100], arr6[100], arr7[100], arr8[100], arr9[100],
arr10[100], arr11[100], arr12[100], arr13[100], arr14[100], arr15[100], arr16[100], arr17[100],
arr18[100],arr19[100],arr20[100];
//完成单链表的创建
L.next = NULL;
library *p, *q;
q = &L;
char buf[100];
ifstream ifs;
ifs.open("text.txt",ios::in);
while (ifs>>buf)
{
p=new library();
strcpy(p->data.name,buf);
ifs>>buf;
strcpy(p->data.num,buf);
ifs>>buf;
strcpy(p->data.tel,buf);
ifs>>buf;
strcpy(p->data.cla,buf);
ifs>>buf;
strcpy(p->data.name1,buf);
ifs>>buf;
strcpy(p->data.time,buf);
ifs>>buf;
strcpy(p->data.adress,buf);
p->next = NULL;
q->next = p; //等于用这条语句:q->next = p;
q = p;
}
ofstream ofs;
ofs.open("text.txt", ios::out);
library *S;
S = L.next;
while (S)
{
ofs << S->data.name << " " << S->data.num << " " << S->data.tel << " " << S->data.cla << " " << S->data.name1 << " " << S->data.time << " " << S->data.adress << " " << endl;
S = S->next;
}
ofs.close();
int x=0,n=0;
char y;
while (1)
{
system("cls");
menu();
cout<<"请输入:";
cin>>x;
if (x <= 0)
{
cout <<endl<< "成功退出系统!" << endl;
break;
}
int check=1;
switch (x)
{
case 1:
cout<<"此操作将覆盖原先所有的信息,确定吗?"<<endl;
cout<<"输入1 确定"<<endl;
cout<<"输入0 取消"<<endl;
cin>>check;
if(check==1)
{
cout << "现在开始录入信息,请输入您要录入几本书的信息" << endl;
cin >> n;
cout<<""<<endl;
L.londecreat(L, n);
cout << "录入完成" << endl;
}
else if(check==0)
{
}
else
{
cout<<"输入有误";
}
break;
case 2:
L.display();
break;
case 3:
cout << "请输入您要进行查找图书的作者名" << endl;
cin >> arr;
L.findname(arr);
break;
case 4:
cout << "请输入您要进行查找图书的图书名" << endl;
cin >> arr2;
L.findbook(arr2);
break;
case 5:
cout << "请输入您要删除图书的登录号" << endl;
cin >> arr4;
L.delete1(L, arr4);
break;
case 6:
cout << "请输入您要进行插入地方的图书的登录号以及插入的图书的登录号,图书名,作者名,分类号,出版单位,出版时间,价格" << endl;
cin >> arr5 >> arr6 >> arr7 >> arr8 >> arr9 >> arr10>> arr11>> arr20;
L.insert(L, arr5, arr6, arr7, arr8, arr9, arr10,arr11,arr20);
break;
case 7:
cout << "请输入您要进行修改的图书的登录号以及您需要修改的图书的登录号,图书名,作者名,分类号,出版单位,出版时间,价格" << endl;
cin >> arr12 >> arr13 >> arr14 >> arr15 >> arr16 >> arr17>> arr18>> arr19;
L.modify(L, arr12, arr13, arr14, arr15, arr16, arr17, arr18,arr19);
break;
case 8:
cout << "已按分类号从大到小排序" << endl<< endl;
L.sort();
break;
default:
cout << "您的输入有误,请重新输入" << endl;
}
cout<<endl<<endl<<"继续吗?"<<endl;
cout<<"输入1 继续"<<endl;
cout<<"输入0 退出"<<endl;
cin>>y;
if(y=='0')
{
cout<<"\n成功退出系统!"<<endl;
break;
}
else if(y=='1')
{
}
else
{
cout<<"输入有误,自动退出系统";
break;
}
}
return 0;
}
总结
对于C语言,要想学好它,重中之重在实践,在于自己动手,要通过不断的上机操作才能更好地学好。
最令我印象深刻的就是单链表了,很轻松就知道以前掌握的不够牢固,现在写完看来,对这块知识已经清晰多了。不仅如此,对文件和流的掌握更深化了,对指针也有了更多的理解。
编写代码的思路很重要,不然便会非常混乱,无从下手。几乎所有代码主要由三部分组成,输入——逻辑——输出。输入部分为检测从键盘上输入的数字,逻辑部分进行判断决定,将输入处理,计算成想要的东西,而输出部分则是在窗口上显示信息。
写打印语句时要写的清晰简洁,可以让使用者更方便的使用程序,所以菜单函数的编写是极其重要的。在实际操作中,我认识到清晰认知每个函数的输入输出可以帮助我更好更快的构建代码,并且这样编写出来的代码bug更少,在调试时也可以更快的找到问题所在,是哪一个函数出了问题,还是主函数的逻辑写错了。在多次循环中,写好缩进可以更好的理清代码的逻辑,使得程序的可读性更强,也让解决bug时也更容易了,这是对自己和对他人都有利的事,不要觉得麻烦。