给需要答辩的友友小小参考
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 50
#define LENTH 20
typedef struct book{
int numBook ; //图书检索号
char name[LENTH],author[LENTH],releaseOrg[LENTH],ISBNnumber[17]; //书名,作者,出版社,ISBN号
float price;
struct book *next;
}books;
int countNumber(int choose,books* H); //统计指定作者或出版商或ISBN号一样的图书数量
int checkISBN(char ISBN[]); //检测ISBN的正确性,对返回1,错的返回0
int checkNumbook(int num_book,books* H); //检查图书编号准确性,对返回1,错的返回0
int displayAllBookInfo(books* H); //显示全部图书信
int enterUI(char passWard[]); //用户登录
books* createBookInfoSystem(); //数据存储读取操作
books* createBookInfoByFile(FILE *fp) ; //文件读取数据
books* createBookInfo(); //用头、尾插法链表创建图书系统图书信息,达到边排序边插入效果
void IU(); //系统界面设计
void SysLoad(); //系统启动
void QueryBySpecialCondition(); //用于IU界面第四个功能模块的内部模块,查询指定条件图书信息
void displayBookInfoByBook_number(int numbook,books* H); //根据图书编号显示图书信息
void deleteBookInfo(books* H); //根据图书编号删除图书信息
void modifiedByBook_number(books *H); //根据图书编号修改图书信息
void saveToFile(books *H); //将数据保存至文件中
void addBookInfo(books* H); //增加图书信息
void Passward(char str[]) ; //初始登录密码
void resetPassward() ; //修改密码
void sortBySpacialCondition(); //根据不同条件进行排序
void sort(books *H,int sortType,char sortBy); //排序通用模块,sortType表示排序方式:1为升序,2为降序排序。sortBy为排序的依据
int main()
{
char passWard[LENTH];
Passward(passWard); //获取密码,默认为000000
if(enterUI(passWard))
{
system("CLS");
printf("\n\t\t登录成功!欢迎使用图书管理系统!\n\n\n");
system("PAUSE");
SysLoad();
system("PAUSE");
return 0;
}
system("CLS");
printf("\n\t登录失败!系统退出!\n");
return 0;
}
void IU() //系统界面设计
{
system("CLS");
printf("\t\t **************** \n");
printf("\t\t ** 欢迎使用 ** \n");
printf("\t\t **************** \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\tAuthor:\t\t薛云腾 \n");
printf("\t\tClass:\t\t计算机二班 \n");
printf("\t\tStuPayroll:\t3110307212 \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t======= *** ===图书管理系统=== *** =======\n");
printf("\t\t== ==\n");
printf("\t\t== ==\n");
printf("\t\t== 1、查看所有图书信息; ==\n");
printf("\t\t== 2、增加图书信息; ==\n");
printf("\t\t== 3、删除图书信息; ==\n");
printf("\t\t== 4、查询相关图书信息; ==\n"); //本查询功能还包括统计功能
printf("\t\t== 5、修改图书信息; ==\n");
printf("\t\t== 6、修改的登录密码; ==\n");
printf("\t\t== 7、通用排序设计模块; ==\n");
printf("\t\t== q/Q、退出; ==\n");
printf("\t\t== ==\n");
printf("\t\t=======****************************=======\n\n\n");
printf("您的选择:");
}
void SysLoad() //系统启动
{
books* H=NULL;
H=createBookInfoSystem();
char choose;
while(1)
{
IU();
scanf("%c",&choose);
getchar();
switch (choose)
{
case '1':
displayAllBookInfo(H);
printf("\n\n\n");
system("PAUSE"); //按任意键继续
break;
case '2':
addBookInfo(H);
break;
case '3':
deleteBookInfo(H);
break;
case '4':
QueryBySpecialCondition();
break;
case '5':
modifiedByBook_number(H);
break;
case '7':
sortBySpacialCondition();
break;
case '6':
resetPassward();
system("CLS");
printf("\n密码已被修改!请重新登陆...\n系统退出...\n\n\n");
exit(0);
case 'q':
case 'Q':
exit(0);
default:
printf("输入错误,请重选...\n\n\n");
system("PAUSE");
break;
}
}
}
void addBookInfo(books* H) //增加图书信息
{
books *p,*r,*h; //p为当前指针,r为信息存储的地址,h为当前结点的前结点
int state=1;
h=H;
p=H->next;
r=(books*)malloc(sizeof(struct book));
r->next=NULL;
system("CLS");
printf("开始添加的图书信息:\n\n\n");
while(1)
{
printf("输入图书编号:");
scanf("%d",&(r->numBook));
if(checkNumbook(r->numBook,H)!=0)
break;
}
printf("请输入书名:");
scanf("%s",r->name);
printf("请输入作者:");
scanf("%s",r->author);
printf("请输入出版社:");
scanf("%s",r->releaseOrg);
printf("请输入价钱:");
scanf("%f",&(r->price));
getchar();
while(1)
{
printf("请输入ISBN号:");
scanf("%s",r->ISBNnumber);
getchar();
if(checkISBN(r->ISBNnumber))
break;
}
while(1)
{
if(p==NULL)
{
r->next=p;
h->next=r;
}
else
{
while(p)
{
if(r->numBook < p->numBook) //编号从小到大排序,输入的num小于链表中的图书编号时候,插于
{
r->next=p;
h->next=r;
state=0;
saveToFile(H);
printf("\n成功添加图书信息!\n\n\n");
system("PAUSE");
return ;
}
h=p;
p=p->next;
}
if(state!=0) //说明插入的图书编号大于所有链表中的图书编号
{
h->next=r;
r->next=p;
saveToFile(H);
printf("\n成功添加图书信息!\n\n\n");
system("PAUSE");
return ;
}
}
}
}
void deleteBookInfo(books* H) //根据图书编号删除图书信息
{
books *p,*pred,*r; //pred指针用来指明要删除的图书的前一个指针
int numbook;
char ch;
printf("输入要删除图书信息的编号:");
scanf("%d",&numbook);
getchar();
pred=H;
p=H->next;
while(p!=NULL)
{
r=pred;
if(p->numBook==numbook)
{
printf("该编号图书信息:\n%s\t%s\t%s\t%s\t\t%.2f\n",p->name,p->author,p->releaseOrg,p->ISBNnumber,p->price);
printf("确认删除?是(y)/否(n): ");
scanf("%c",&ch);
getchar();
if('y'==ch|| 'Y'==ch)
{
r->next=p->next;
p=NULL;
saveToFile(H);
printf("删除成功!\n\n\n");
system("PAUSE");
return ;
}
printf("未删除...\n\n\n");
system("PAUSE");
return ;
}
else
{
pred=p;
p=p->next;
}
}
printf("该编号不存在!删除失败...\n\n\n");
system("PAUSE");
}
void modifiedByBook_number(books *H) //根据图书编号修改图书信息
{
int bookNumber;
books *p=NULL;
while(1)
{
system("CLS");
printf("输入要修改图书的编号:");
scanf("%d",&bookNumber);
getchar();
p=H->next;
while(p!=NULL)
{
if(p->numBook==bookNumber)
{
printf("\n开始更新图书信息...\n\n");
printf("请输入书名:");
scanf("%s",p->name);
printf("请输入作者:");
scanf("%s",p->author);
printf("请输入出版社:");
scanf("%s",p->releaseOrg);
printf("请输入价钱:");
scanf("%f",&p->price);
getchar();
while(1)
{
printf("请输入ISBN号:");
scanf("%s",p->ISBNnumber);
getchar();
if(checkISBN(p->ISBNnumber)==1)
break;
}
saveToFile(H);
printf("\n\n修改成功!!\n\n\n");
system("PAUSE");
return;
}
p=p->next;
}
printf("\n输入错误,该编号不存在!\n\n\n");
system("PAUSE");
}
}
void QueryBySpecialCondition() //用于IU界面第四个功能模块的内部模块,查询指定条件图书信息
{
int bookNumber;
char choose,AuthOrOrgOrISBN[LENTH];
books* H=NULL;
H=createBookInfoSystem();
while(1)
{
system("CLS");
printf("1、查询指定编号的图书信息;\n");
printf("2、查询指定的ISBN号的图书数量;\n");
printf("3、查询指定作者的图书数量;\n");
printf("4、查询指定出版商的图书数量;\n");
printf("按任意键返回上一级;\n\n\n");
printf("您的选择:");
scanf("%c",&choose);
switch (choose)
{
case '1':
printf("输入要查询的图书编号:");
scanf("%d",&bookNumber);
getchar();
system("CLS");
displayBookInfoByBook_number(bookNumber,H);
printf("\n\n\n");
system("PAUSE");
break;
case '2':
system("CLS");
printf("该ISBN号图书数量为:%d",countNumber(1,H));
printf("\n\n\n");
system("PAUSE");
break;
case '3':
system("CLS");
printf("该作者的图书数量为:%d",countNumber(2,H));
printf("\n\n\n");
system("PAUSE");
break;
case '4':
system("CLS");
printf("该出版社的图书数量为:%d",countNumber(3,H));
printf("\n\n\n");
system("PAUSE");
break;
default:
getchar();
return;
break;
}
}
}
int countNumber(int choose,books* H) //统计指定作者或出版商或ISBN号一样的图书数量
{
books *p;
int cnt=0;
char AuthOrOrgOrISBN[LENTH];
p=H->next;
switch(choose)
{
case 1:
printf("输入ISBN号:");
scanf("%s",AuthOrOrgOrISBN);
getchar();
if(checkISBN(AuthOrOrgOrISBN)==0)
{
printf("该ISBN不存在!\n");
return -1;
}
while(p!=NULL)
{
if(strcmp(p->ISBNnumber,AuthOrOrgOrISBN)==0)
cnt++;
p=p->next;
}
break;
case 2:
printf("输入图书作者:");
scanf("%s",AuthOrOrgOrISBN);
getchar();
while(p!=NULL)
{
if(strcmp(p->author,AuthOrOrgOrISBN)==0)
cnt++;
p=p->next;
}
break;
case 3:
printf("输入图书出版社名字:");
scanf("%s",AuthOrOrgOrISBN);
getchar();
while(p!=NULL)
{
if(strcmp(p->releaseOrg,AuthOrOrgOrISBN)==0)
cnt++;
p=p->next;
}
break;
default:
printf("无符合查询的条件!");
return -1;
}
return cnt;
}
books* createBookInfo() //用头、尾插法链表创建图书系统图书信息,达到边排序边插入效果
{
struct book *head,*p,*r,*h,*q; //r为尾指针,h为头结点的指针,用于头插法.q用于循环遍历链表
int state=1;
head=(struct book *)malloc(sizeof(struct book));
r=head;
h=head;
r->next=NULL;
int num;
system("CLS");
printf("开始构建图书系统\n\n");
printf("输入图书编号,以0结束:");
scanf("%d",&num);
getchar();
while(num) //以检索号输入为0结束输入
{
q=head->next;
if(checkNumbook(num,head)==1)
{
p=(struct book *)malloc(sizeof(struct book));
p->next=NULL;
p->numBook=num;
printf("输入图书名字:");
scanf("%s",p->name);
printf("输入图书作者:");
scanf("%s",p->author);
printf("输入图书出版社:");
scanf("%s",p->releaseOrg);
while(1)
{
printf("输入图书ISBN号:");
scanf("%s",p->ISBNnumber);
if(checkISBN(p->ISBNnumber))
break;
}
printf("输入图书单价:");
scanf("%f",&(p->price));
getchar();
if(q==NULL)
{
p->next=q;
h->next=p;
}
else
{
while(q)
{
if(p->numBook < q->numBook) //编号从小到大排序,输入的num小于链表中的图书编号时候,插于
{
p->next=q;
h->next=p;
state=0;
break;
}
h=q;
q=q->next;
}
if(state) //说明插入的图书编号大于所有链表中的图书编号
{
h->next=p;
p->next=q;
}
}
}
printf("输入图书编号,以0结束:");
scanf("%d",&num);
getchar();
}
printf("\n\n图书系统构建完成!欢迎使用...\n\n\n");
system("PAUSE");
saveToFile(head);
return head;
}
int checkISBN(char ISBN[]) //检测ISBN的正确性,对返回1,错的返回0
{
int i=0;
if(ISBN[3]=='-' && ISBN[5]=='-' && ISBN[9]=='-' && ISBN[15]=='-')
{
for(;i<17;i++) //ISBN为17为字符(其中字符为数字和-)
{
if( i!=3 && i!=5 && i!=9 && i!=15 )
{
if( ISBN[i]<48 || ISBN[i]>57 )
break;
}
}
if(i==17)
return 1;
}
printf("ISBN格式错误!!!\n");
return 0;
}
int checkNumbook(int num_book,books* H) //检查图书编号准确性,对返回1,错的返回0
{
books *p;
p=H->next;
while(p!=NULL)
{
if(p->numBook==num_book)
{
printf("图书编号存在,输入错误!\n");
return 0;
}
p=p->next;
}
return 1;;
}
int displayAllBookInfo(books* H) //显示全部图书信息
{
system("CLS");
books *p=H->next;
while(p!=NULL)
{
printf("%d\t%s\t%s\t%s\t%.2f\t%s\n",p->numBook,p->name,p->author,p->releaseOrg,p->price,p->ISBNnumber);
p=p->next;
}
return 0;
}
void displayBookInfoByBook_number(int numbook,books* H) //根据图书编号显示图书信息
{
books *p;
p=H->next;
printf("按默认的编号升序显示:\n\n");
while(p!=NULL)
{
if(p->numBook==numbook){
printf("%s\t%s\t%s\t%s\t%.2f\n",p->name,p->author,p->releaseOrg,p->ISBNnumber,p->price);
return ;
}
p=p->next;
}
printf("输入错误,该图书编号不存在!\n");
}
books* createBookInfoSystem() //数据存储读取操作
{
FILE *fp=NULL;
if((fp=fopen("bookInfo.txt","rt"))==NULL) //如果数据文件存在,从文件读取 否则,手动创建
{
if((fp=fopen("bookInfo.txt.txt","wt"))==NULL)
exit(0);
else
return createBookInfo();
}
return createBookInfoByFile(fp);
}
books* createBookInfoByFile(FILE *fp) //文件读取数据
{
books *head,*p,*r,*h; //r为尾指针,h为头结点的指针,用于头插法
head=(struct book *)malloc(sizeof(struct book));
r=head;
h=head;
r->next=NULL;
//int num;
while(!feof(fp))
{
p=(struct book *)malloc(sizeof(struct book));
p->next=NULL;
fscanf(fp,"%d%s%s%s%f%s",&(p->numBook),p->name,p->author,p->releaseOrg,&(p->price),p->ISBNnumber);
r->next=p;
r=p;
}
fclose(fp);
printf("图书系统构建完成!欢迎使用...\n\n");
return head;
}
void saveToFile(books *H) //将数据保存至文件中
{
FILE *fp;
books *point=NULL,*ront;
if((fp=fopen("bookInfo.txt","w"))==NULL)
{
printf("文件打开失败!");
exit(0);
}
point=H->next;
while(point)
{
ront=point->next;
if(ront)
fprintf(fp,"%d\t\t%s\t\t%s\t\t%s\t\t%.2f\t%s\n",point->numBook,point->name,point->author,point->releaseOrg,point->price,point->ISBNnumber);
else
fprintf(fp,"%d\t\t%s\t\t%s\t\t%s\t\t%.2f\t%s",point->numBook,point->name,point->author,point->releaseOrg,point->price,point->ISBNnumber);
point=point->next;
}
fclose(fp);
}
void Passward(char str[]) //登录密码
{
char passward[LENTH]="000000";
FILE *fp;
if((fp=fopen("passward.txt","r"))==NULL)
{
printf("密码文件不存在!默认密码创建\n");
if((fp=fopen("passward.txt","w"))==NULL)
{
printf("默认密码文件创建失败!退出..");
exit(0);
}
fprintf(fp,"%s",passward);
printf("默认密码文件创建成功!");
fclose(fp);
}
fscanf(fp,"%s",passward);
strcpy(str,passward);
fclose(fp);
}
int enterUI(char passWard[]) //用户登录
{
char userEntry[LENTH],ch;
while(1)
{
system("CLS");
printf("\t\t\twelcome to use BookInfoSystem\n\n");
printf("用户:administate\n");
printf("密码:");
scanf("%s",userEntry);
getchar();
if(strcmp(passWard,userEntry)==0 ) //密码匹配成功,进入系统
return 1;
printf("\n密码错误,继续尝试?是(y)/否(n):");
scanf("%c",&ch);
getchar();
if(ch!='y' && ch!='Y')
return 0;
}
}
void resetPassward() //修改密码
{
FILE *fp;
char newPassward[LENTH],temp[LENTH];
if((fp=fopen("passward.txt","w"))==NULL)
{
printf("\n密码文件打开发生错误!暂时不能修改登录密码!\n");
return ;
}
while(1)
{
system("CLS");
printf("请输入新密码:");
scanf("%s",newPassward);
getchar();
printf("再一次输入新密码:");
scanf("%s",temp);
getchar();
if(strcmp(newPassward,temp)==0)
{
fprintf(fp,"%s",newPassward);
fclose(fp);
system("CLS");
printf("\n密码修改成功!\n\n");
system("PAUSE");
return;
}
printf("\n两次密码输入不同,请重设...\n\n\n");
system("PAUSE");
}
}
void sortBySpacialCondition() //根据不同条件进行排序
{
char choose;
books* H=NULL;
H=createBookInfoSystem();
while(1){
system("CLS");
printf("升序:\n");
printf(" 1.按照图书编号升序;\n");
printf(" 2.按照图书出版商升序;\n");
printf(" 3.按照图书书名升序;\n");
printf(" 5.按照图书价格升序;\n");
printf("降序:\n");
printf(" 6.按照图书编号降序;\n");
printf(" 7.按照图书出版商降序;\n");
printf(" 8.按照图书书名降序;\n");
printf(" 9.按照图书作者降序;\n");
printf(" A.按照图书价格降序;\n");
printf(" 按其他任意键返回上一级菜单\n\n");
printf("您的选择:");
scanf("%c",&choose);
getchar();
switch (choose)
{
case '1':
sort(H,1,choose);
break;
case '2':
sort(H,1,choose);
break;
case '3':
sort(H,1,choose);
break;
case '4':
sort(H,1,choose);
break;
case '5':
sort(H,1,choose);
break;
case '6':
sort(H,2,choose);
break;
case '7':
sort(H,2,choose);
break;
case '8':
sort(H,2,choose);
break;
case '9':
sort(H,2,choose);
break;
case 'A':
case 'a':
sort(H,2,choose);
break;
default:
return ;
}
}
}
void sort(books *H,int sortType,char sortBy) //排序通用模块,sortType表示排序方式:1为升序,2为降序排序。sortBy为排序的依据
{
books *newBooks,*s,*p,*q; //newBook用于存储新的链表头,s指代遍历时当前指针
newBooks=(books*)malloc(sizeof(struct book));
newBooks->next=NULL;
if(sortType==1)
{
while(H->next)
{
p=(books *)malloc(sizeof(struct book));
(*p)=*H->next; //copy一份当前指针
p->next=NULL;
s=newBooks;
if(sortBy=='1')
{
newBooks=H;
break;
}
else if(sortBy=='2')
while(s->next && strcmp(p->releaseOrg,s->next->releaseOrg)>0)
s=s->next;
else if(sortBy=='3')
while(s->next && strcmp(p->name,s->next->name)>0)
s=s->next;
else if(sortBy=='4')
while(s->next && strcmp(p->author,s->next->author)>0)
s=s->next;
else if(sortBy=='5')
while(s->next && abs(p->price-s->next->price)>0)
s=s->next;
p->next=s->next;
s->next=p;
H=H->next;
}
}
if(sortType==2)
{
while(H->next)
{
p=(books *)malloc(sizeof(struct book));
(*p)=*H->next; //copy一份当前指针
p->next=NULL;
s=newBooks;
if(sortBy=='6')
while(s->next && p->numBook<s->next->numBook)
s=s->next;
else if(sortBy=='7')
while(s->next && strcmp(p->releaseOrg,s->next->releaseOrg)<0)
s=s->next;
else if(sortBy=='8')
while(s->next && strcmp(p->name,s->next->name)<0)
s=s->next;
else if(sortBy=='9')
while(s->next && strcmp(p->author,s->next->author)<0)
s=s->next;
else if(sortBy=='A' || sortBy=='a')
while(s->next && abs(p->price-s->next->price)<0)
s=s->next;
p->next=s->next;
s->next=p;
H=H->next;
}
}
q=newBooks->next;
printf("\n");
while(q)
{
printf("%d\t%s\t%s\t%s\t%.2f\t%s\n",q->numBook,q->name,q->author,q->releaseOrg,q->price,q->ISBNnumber);
q=q->next;
}
printf("\n\n\n");
system("PAUSE");
}