前言
最近自己写了一个图书管理系统,陆陆续续的摸索着往里面加功能。下一个目标是用EasyX写一个图形界面出来,或者实现群体借阅这样子。完成之后会在本篇文章进行更新。
如果有bug还望各位同袍在评论区告知。
代码
#include<stdio.h>
#include<Windows.h>
#include<ctype.h>
#include<string.h>
#include <stdlib.h>
#include <stddef.h>
#include "graphics.h"
#include "genlib.h"
#include "conio.h"
#include <olectl.h>
#include <mmsystem.h>
#include <wingdi.h>
#include <ole2.h>
#include <ocidl.h>
#include <winuser.h>
#define DEADLINE 30//借书期限30天
//结构体
struct Date
{
int year,month,day;
};
struct Book
{
char num[30];//书号
char title[30];//书名
char author[4][60];//作者,最多三人
char key[6][60];//关键词,最多五个
char publisher[20];//出版社
char publishdate[30];//出版日期
char available;//是否可借
char id[10];//被谁借走
struct Book *next;
};
struct History//借阅历史
{
char id[10];//借的人的用户号
char num[30];//被借的书号
struct Date borrow_date;//借书日期
struct Date return_date;//还书日期
struct History *next;
};
struct User//用户
{
char id[10];//用户号
char name[10];//姓名
char working[15];//工作单位
char gender;//性别
struct User *next;
};
//全局变量
struct User *user_h = NULL;//用户头指针
struct Book *book_h = NULL;//书头指针
struct History *history_h = NULL;//借阅历史头指针
//初始化
void initialization(void)
{
FILE *fp;
fp=fopen("user.txt","wb"); fclose(fp);
fp=fopen("book.txt","wb"); fclose(fp);
fp=fopen("history.txt","wb"); fclose(fp);
}
void read_file(void)//读文件
{
FILE *fp;
struct User *user_p1=NULL;
struct User *user_p2=NULL;
struct Book *book_p1=NULL;
struct Book *book_p2=NULL;
struct History *history_p1=NULL;
struct History *history_p2=NULL;
//读
if((fp=fopen("user.txt","rb"))==NULL) fp=fopen("user.txt","wb+");//打开失败则重新创建
user_h=user_p1=user_p2 = (struct User*)malloc(sizeof(struct User));
fread(user_p1,sizeof(struct User),1,fp);
while(!feof(fp))
{
user_p1=user_p2;
user_p2=(struct User *)malloc(sizeof(struct User));
user_p1->next=user_p2;
fread(user_p2,sizeof(struct User),1,fp);
}
if(user_p1==user_p2) user_h=NULL;//文件为空
else user_p1->next=NULL;
free(user_p2);
fclose(fp);
//写
if((fp=fopen("book.txt","rb"))==NULL) fp=fopen("book.txt","wb+");//打开失败则重新创建
book_h=book_p1=book_p2 = (struct Book*)malloc(sizeof(struct Book));
fread(book_p1,sizeof(struct Book),1,fp);;
while(!feof(fp))
{
book_p1=book_p2;
book_p2=(struct Book *)malloc(sizeof(struct Book));
book_p1->next=book_p2;
fread(book_p2,sizeof(struct Book),1,fp);
}
if(book_p1==book_p2) book_h=NULL;//文件为空
else book_p1->next=NULL;
free(book_p2);
fclose(fp);
//读借阅历史
if((fp=fopen("history.txt","rb"))==NULL) fp=fopen("history.txt","wb+");//打开失败则重新创建
history_h=history_p1=history_p2 = (struct History*)malloc(sizeof(struct History));
fread(history_p1,sizeof(struct History),1,fp);
while(!feof(fp))
{
history_p1=history_p2;
history_p2=(struct History *)malloc(sizeof(struct History));
history_p1->next=history_p2;
fread(history_p2,sizeof(struct History),1,fp);
}
if(history_p1==history_p2) history_h=NULL;//文件为空
else history_p1->next=NULL;
free(history_p2);
fclose(fp);
}
void write_file(void)//写文件
{
FILE *fp;
struct User *user_p1=NULL;
struct User *user_p2=NULL;
struct Book *book_p1=NULL;
struct Book *book_p2=NULL;
struct History *history_p1=NULL;
struct History *history_p2=NULL;
//写用户文件
fp=fopen("user.txt","wb");
if(user_h!=NULL)
{
user_p1=user_p2=user_h;
while(user_p2!=NULL)
{
user_p1=user_p2;
fwrite(user_p1,sizeof(struct User),1,fp);
user_p2=user_p1->next;
}
}
fclose(fp);
//写书文件
fp=fopen("book.txt","wb");
if(book_h!=NULL)
{
book_p1=book_p2=book_h;
while(book_p2!=NULL)
{
book_p1=book_p2;
fwrite(book_p1,sizeof(struct Book),1,fp);
book_p2=book_p1->next;
}
}
fclose(fp);
//写借阅历史文件
fp=fopen("history.txt","wb");
if(history_h!=NULL)
{
history_p1=history_p2=history_h;
while(history_p2!=NULL)
{
history_p1=history_p2;
fwrite(history_p1,sizeof(struct History),1,fp);
history_p2=history_p1->next;
}
}
fclose(fp);
}
void freeall(void)//释放空间
{
struct User *user_p1=NULL;
struct User *user_p2=NULL;
struct Book *book_p1=NULL;
struct Book *book_p2=NULL;
struct History *history_p1=NULL;
struct History *history_p2=NULL;
if(user_h!=NULL)
{
user_p1=user_p2=user_h;
while(user_p2!=NULL)
{
user_p1=user_p2;
user_p2=user_p1->next;
free(user_p1);
}
user_h=NULL;
}
if(book_h!=NULL)
{
book_p1=book_p2=book_h;
while(book_p2!=NULL)
{
book_p1=book_p2;
book_p2=book_p1->next;
free(book_p1);
}
book_h=NULL;
}
if(history_h!=NULL)
{
history_p1=history_p2=history_h;
while(history_p2!=NULL)
{
history_p1=history_p2;
history_p2=history_p1->next;
free(history_p1);
}
history_h=NULL;
}
}
//转换大小写并消除回车
char upper_getchar(void)
{
char ch;
while (ch = toupper(getchar()))
{
if (ch == '\n')
continue;
else
break;
}
return ch;
}
int datecmp(struct Date start,struct Date end)//算日期是否合法
{
if(start.year*10000 + start.month*100 + start.day <= end.year*10000 + end.month*100 + end.day)
return 1;
else
return -1;
}
int cal_date(struct Date start,struct Date end)//算日期间隔
{
if(datecmp(start,end)==-1)
{
puts("日期错误");
return -1;
}
else
{
int y1,m1,d1;
int y2,m2,d2;
m1 = (start.month + 9) % 12;
y1 = start.year - m1/10;
d1 = 365*y1 + y1/4 - y1/100 + y1/400 + (m1*306 + 5)/10 + (start.day - 1);
m2 = (end.month + 9) % 12;
y2 = end.year- m2/10;
d2 = 365*y2 + y2/4 - y2/100 + y2/400 + (m2*306 + 5)/10 + (end.day - 1);
return (d2 - d1);
}
}
void query(void)//主查询系统
{
struct User *user_p1=NULL;
struct Book *book_p1=NULL;
struct History *history_p1=NULL;
struct User *user_p2=NULL;
struct Book *book_p2=NULL;
struct History *history_p2=NULL;
char buffer_num[30];//书号
char buffer_id[30];//用户号
char option;//
system("cls");
do
{
puts("************查询系统************");
puts("A.图书查询");
puts("B.学生信息查询");
puts("C.历史信息查询");
puts("D.催还图书");
puts("Q.返回主系统");
puts("请输入选项。之后按回车键确认");
switch(option = upper_getchar())
{
case 'A':puts("请输入书号,按回车键确认");
scanf("%s",buffer_num);
search_book(buffer_num,&book_p1,&book_p2);
break;
case 'B':puts("请输入用户号,按回车键确认");
scanf("%s",buffer_id);
search_user(buffer_id,&user_p1,&user_p2);
break;
case 'C':puts("请输入用户号,按回车键确认");
scanf("%s",buffer_id);
search_history(buffer_id,"ALL",&history_p1,&history_p2);
break;
case 'D':return_book_now();
default:puts("\n\n请输入对应操作的字母");
system("Pause");
break;
}
system("cls");
}while(option != 'Q');
}
int search_book(char num[],struct Book **book_p1,struct Book **book_p2)//查书
{
int flag=0;//标记是否找到
*book_p1=*book_p2=book_h;
while(*book_p2!=NULL)
{
if(strcmp(num,(*book_p2)->num)==0)
{
flag=1;
break;
}
*book_p1=*book_p2;
*book_p2=(*book_p1)->next;
}
if(flag)//已找到
{
puts("已找到");
printf("书名: %s\n书号: %s\n出版社: %s\n作者: %s %s %s\n关键词: %s %s %s %s %s\n",
(*book_p2)->title,(*book_p2)->num,
(*book_p2)->publisher,(*book_p2)->author[0],(*book_p2)->author[1],(*book_p2)->author[2],
(*book_p2)->key[0],(*book_p2)->key[1],(*book_p2)->key[2],(*book_p2)->key[3],(*book_p2)->key[4]);
printf("被谁借走: %s\n",(*book_p2)->id);
}
else
puts("无记录\n");
system("pause");
return flag;
}
int search_user(char id[],struct User **user_p1,struct User **user_p2)//查询用户。p1为前一个指针,p2是待查项指针
{
int flag=0;//标记是否找到
*user_p1=*user_p2=user_h;
while(*user_p2!=NULL)
{
if(strcmp(id,(*user_p2)->id)==0)
{
flag=1;
break;
}
*user_p1=*user_p2;
*user_p2=(*user_p1)->next;
}
if(flag)//已找到
{
puts("已找到");
printf("用户: %s\n姓名: %s\n工作地点: %s\n性别: %s\n",(*user_p2)->id,(*user_p2)->name,(*user_p2)->working,(*user_p2)->gender);
}
else
puts("无记录\n");
system("pause");
return flag;
}
int search_history(char id[],char num[],struct History **history_p1,struct History **history_p2)//查询借阅历史。p1为前一个指针,p2是待查项指针
{
int flag=0;
*history_p1=*history_p2=history_h;
if(strcmp(num,"ALL")==0)
{
while(*history_p2!=NULL)
{
if((strcmp(id,(*history_p2)->id)==0))
{
flag=1;
printf("用户号: %s\n书号: %s\n借书日期:%d/%d/%d\n还书日期:%d/%d/%d\n",
(*history_p2)->id,(*history_p2)->num,
(*history_p2)->borrow_date.year,(*history_p2)->borrow_date.month,(*history_p2)->borrow_date.day,
(*history_p2)->return_date.year,(*history_p2)->return_date.month,(*history_p2)->return_date.day);
puts("**********************");
}
*history_p1=*history_p2;
*history_p2=(*history_p1)->next;
}
puts("**********************");
system("pause");
}
else
{
while(*history_p2!=NULL)
{
if(strcmp(id,(*history_p2)->id)==0&&strcmp(num,(*history_p2)->num)==0&&(*history_p2)->return_date.year==0)//用户号和书号均找到且没有还书
{
flag=1;
break;
}
*history_p1=*history_p2;
*history_p2=(*history_p1)->next;
}
if(flag)
{
puts("找到了");
printf("用户号: %s\n书号: %s\n借书日期:%d/%d/%d\n还书日期:%d/%d/%d\n",
(*history_p2)->id,(*history_p2)->num,
(*history_p2)->borrow_date.year,(*history_p2)->borrow_date.month,(*history_p2)->borrow_date.day,
(*history_p2)->return_date.year,(*history_p2)->return_date.month,(*history_p2)->return_date.day);
}
else
puts("无记录");
system("pause");
}
return flag;
}
void return_book_now(void)//催还书
{
struct History *history_p;
struct User *user_p1=NULL;
struct User *user_p2=NULL;
struct Date date;
puts("输入今日日期");
scanf("%d%d%d",&date.year,&date.month,&date.day);
history_p=history_h;
while(history_p!=NULL)
{
if(history_p->return_date.year==0&&cal_date(history_p->borrow_date,date)>DEADLINE)//逾期未还
{
printf("该还书了。书号: %s\n用户号: %s\n",history_p->num,history_p->id);
search_user(history_p->id,&user_p1,&user_p2);
puts("****************************************");
}
history_p=history_p->next;
}
system("pause");
}
void user_management(void)//用户主管理系统
{
char option;
system("cls");
do
{
puts("************用户信息管理************");
puts("A.添加用户信息");
puts("B.修正用户信息");
puts("C.删除用户信息");
puts("D.查看用户信息");
puts("Q.返回主系统");
puts("请输入选项。之后按回车键确认");
switch (option = upper_getchar())
{
case 'A':add_user(); break;
case 'B':modify_user(); break;
case 'C':delete_user(); break;
case 'D':view_user(); break;
case 'Q':break;
default:puts("\n\n请输入对应操作的字母");
system("Pause");
break;
}
system("cls");
}while(option != 'Q');
}
void add_user(void)//添加用户
{
char option;
struct User *user_p1=NULL;
struct User *user_p2=NULL;
struct User user;
puts("请输入用户号");
printf("用户号: ");
scanf("%s",user.id);
if(search_user(user.id,&user_p1,&user_p2)==1)//重复了
{
puts("已有该用户");
Sleep(1000);
return;
}
puts("请填写该新用户详细信息,回车键录入");
printf("用户号: %s\n",user.id);
printf("姓名: ");
scanf("%s",&user.name);
puts("姓名已录入");
printf("工作地点: ");
scanf("%s",&user.working);
puts("工作地点已录入");
printf("性别: ");
user.gender=upper_getchar();
puts("性别已录入");
user.next=NULL;
puts("是否保存,输入Y/N");
do
{
option=upper_getchar();
if(option=='Y')
{
user_p2=(struct User *)malloc(sizeof(struct User));
*user_p2=user;
system("pause");
if(user_h==NULL)
user_h=user_p2;
else
user_p1->next=user_p2;
puts("录入成功");
Sleep(500);
}
}while(!(option=='Y' || option=='N'));
}
void modify_user(void)//修正用户
{
char option;
struct User user;
struct User *user_p1=NULL;
struct User *user_p2=NULL;
puts("请输入用户号");
printf("用户号: ");
scanf("%s",&user.id);
if(search_user(user.id,&user_p1,&user_p2)==0)//用户不存在
{
Sleep(1000);
return;
}
puts("请填写信息,回车键录入");
printf("姓名: ");
scanf("%s",&user.name);
puts("姓名已录入");
printf("工作地点: ");
scanf("%s",&user.working);
printf("工作地点已录入");
printf("性别: ");
user.gender=upper_getchar();
puts("性别已录入");
puts("是否保存,请输入Y/N");
user.next=user_p2->next;
do
{
option=upper_getchar();
if(option=='Y')
{
*user_p2=user;//写进去,覆盖,再输入替换
puts("录入成功");
Sleep(500);
}
}while(!(option=='Y' || option=='N'));
}
void delete_user(void)//删除用户
{
char option;
struct User user;
struct User *user_p1=NULL;
struct User *user_p2=NULL;
puts("请输入用户号");
printf("用户号: ");
scanf("%s",&user.id);
if(search_user(user.id,&user_p1,&user_p2)==0)//用户不存在
{
Sleep(1000);
return;
}
else//p2指针在要删除的学生处,p1是p2之前的
{
puts("是否删除?输入Y/N");
do
{
option=upper_getchar();
if(option=='Y')
{
if(user_p2==user_h)
user_h=user_p2->next;
else
user_p1->next=user_p2->next;
free(user_p2);
puts("录入成功");
Sleep(1000);
return;
}
}while(!(option=='Y' || option=='N'));
}
}
void view_user(void)//查看用户信息
{
struct User *user_p;
user_p=user_h;
while(user_p!=NULL)
{
printf("用户号:%s \n姓名:%s \n工作地点:%s \n性别:%c \n",user_p->id,user_p->name,user_p->working,user_p->gender);
printf("************************************\n");
user_p=user_p->next;
}
system("pause");
}
//图书管理系统
void book_management(void)//图书主管理系统
{
char option;
system("cls");
do
{
puts("************图书管理************");
puts("A.添加新书");
puts("B.修改图书信息");
puts("C.删除图书");
puts("D.查看图书信息");
puts("Q.返回图书管理主系统");
puts("请输入选项。之后按回车键确认");
switch (option = upper_getchar())
{
case 'A':add_book(); break;
case 'B':modify_book(); break;
case 'C':delete_book(); break;
case 'D':view_book(); break;
case 'Q':break;
default:puts("\n\n请输入对应操作的字母");
system("Pause");
break;
}
system("cls");
}while (option != 'Q');
}
void add_book(void)//加书
{
char option;
struct Book book;
struct Book *book_p1=NULL;
struct Book *book_p2=NULL;
puts("请输入书号");
printf("书号: ");
scanf("%s",&book.num);
if(search_book(book.num,&book_p1,&book_p2)==1)
{
puts("已有此书记录");
Sleep(1000);
return;
}
strcpy(book.id,"无");
puts("请填写该书信息,回车键录入");
printf("书号:%s \n",book.num);
printf("书名: ");
scanf("%s",&book.title);
puts("书名已录入");
printf("作者(最多三位,没有的话请输入无): ");
scanf("%s %s %s",&book.author[0],&book.author[1],&book.author[2]);
puts("作者已录入");
printf("出版社: ");
scanf("%s",&book.publisher);
puts("出版社已录入");
printf("关键词(最多五个,没有的话请输入无): ");
scanf("%s %s %s %s %s",&book.key[0],&book.key[1],&book.key[2],&book.key[3],&book.key[4]);
puts("关键词已录入");
puts("是否保存,请输入Y/N");
book.next=NULL;
do
{
option=upper_getchar();
if(option=='Y')
{
book_p2 = (struct Book*)malloc(sizeof(struct Book));
*book_p2=book;
if(book_h==NULL)
book_h=book_p2;
else
book_p1->next=book_p2;
puts("录入成功");
Sleep(500);
}
}while(!(option=='Y'||option=='N'));
}
void modify_book(void)//修改书的信息
{
char option;
struct Book book;
struct Book *book_p1=NULL;
struct Book *book_p2=NULL;
puts("请输入书号");
printf("书号: ");
scanf("%s",&book.num);
if(search_book(book.num,&book_p1,&book_p2)==0)
{
Sleep(1000);
return;
}
puts("请填写该书信息,回车键录入");
printf("书号:%s\n",book.num);
printf("书名: ");
scanf("%s",&book.title);
puts("书名已录入");
printf("作者(最多三位,没有的话请输入无): ");
scanf("%s %s %s",&book.author[0],&book.author[1],&book.author[2]);
puts("作者已录入");
printf("出版社: ");
scanf("%s",&book.publisher);
puts("出版社已录入");
printf("关键词(最多五个,没有的话请输入无): ");
scanf("%s %s %s %s %s",&book.key[0],&book.key[1],&book.key[2],&book.key[3],&book.key[4]);
puts("关键词已录入");
book.available=book_p2->available;//初始化
book.next=book_p2->next;
puts("是否保存,请输入Y/N");
do
{
option=upper_getchar();
if(option=='Y')
{
*book_p2=book;
puts("录入成功");
Sleep(500);
}
}while(!(option=='Y'||option=='N'));
}
void delete_book(void)//删掉书
{
char option;
struct Book book;
struct Book *book_p1=NULL;
struct Book *book_p2=NULL;
puts("请输入书号");
printf("书号: ");
scanf("%s",&book.num);
if(search_book(book.num,&book_p1,&book_p2)==0)
{
Sleep(1000);
return;
}
else//一旦找到了,p2指针就在要删除的图书处
{
puts("是否删除?输入Y/N");
do
{
option=upper_getchar();
if(option=='Y')
{
if(book_p2==book_h)
book_h=book_p2->next;
else
book_p1->next=book_p2->next;
free(book_p2);
puts("删除成功");
Sleep(1000);
return;
}
}while(!(option=='Y'||option=='N'));
}
}
void view_book(void)//查看图书
{
struct Book *book_p;
book_p=book_h;
while(book_p!=NULL)
{
printf("书名:%s \n书号:%s \n出版社:%s \n作者:%s %s %s\n关键词:%s %s %s %s %s\n",
book_p->title,book_p->num,
book_p->publisher,book_p->author[0],book_p->author[1],book_p->author[2],
book_p->key[0],book_p->key[1],book_p->key[2],book_p->key[3],book_p->key[4]);
printf("************************************\n");
book_p=book_p->next;
}
system("pause");
}
//借书或还书
void borrow_or_return_book(void)
{
char option;
system("cls");
do
{
puts("************借书或还书************");
puts("A.借书");
puts("B.还书");
puts("Q.返回图书管理主系统");
puts("请输入选项:按回车键确认,大小写均可");
switch(option = upper_getchar())
{
case 'A':borrow_book(); break;
case 'B':return_book(); break;
case 'Q':break;
default:puts("\n\n请输入对应操作的字母");
system("Pause");
break;
}
system("cls");
} while (option != 'Q');
}
void borrow_book(void)//借书
{
char option;
struct User user;
struct User *user_p1=NULL;
struct User *user_p2=NULL;
struct Book book;
struct Book *book_p1=NULL;
struct Book *book_p2=NULL;
struct History history;
struct History *history_p1=NULL;
struct History *history_p2=NULL;
puts("请输入用户号");
printf("用户号: ");
scanf("%s",&user.id);
if(search_user(user.id,&user_p1,&user_p2)==0)
{
Sleep(1000);
return;
}
puts("请输入书号");
printf("书号: ");
scanf("%s",&book.num);
if(search_book(book.num,&book_p1,&book_p2)==0)
{
Sleep(1000);
return;
}
if(book_p2->available=='N')
{
puts("此书已被借走");
system("pause");
return;
}
search_history(user.id,book.num,&history_p1,&history_p2);
book=*book_p2;
book.available='N';
strcpy(book.id,user.id);
puts("请输入借书时间");
scanf("%d%d%d",&history.borrow_date.year,&history.borrow_date.month,&history.borrow_date.day);
strcpy(history.num,book.num);
strcpy(history.id,user.id);
history.return_date.day=0;
history.return_date.month=0;
history.return_date.year=0;
history.next=NULL;
puts("是否借书,请输入Y/N");
do
{
option=upper_getchar();
if(option=='Y')
{
*book_p2=book;
history_p2=(struct History *)malloc(sizeof(struct History));
*history_p2=history;
if(history_h==NULL)
history_h=history_p2;
else
history_p1->next=history_p2;
puts("录入成功");
Sleep(500);
}
}while(!(option=='Y'||option=='N'));
}
void return_book(void)//还书
{
char option;
struct History history;
struct Book book;
struct History *history_p1=NULL;
struct History *history_p2=NULL;
struct Book *book_p1=NULL;
struct Book *book_p2=NULL;
puts("请输入用户号");
printf("用户号: ");
scanf("%s",&history.id);
puts("请输入书号");
printf("书号: ");
scanf("%s",&history.num);
if(search_history(history.id,history.num,&history_p1,&history_p2)==0)
{
Sleep(1000);
return;
}
history=*history_p2;
search_book(history.num,&book_p1,&book_p2);
book=*book_p2;
book.available='Y';
strcpy(book.id,"无");
puts("请输入还书时间");
scanf("%d%d%d",&history.return_date.year,&history.return_date.month,&history.return_date.day);
puts("是否还书,请输入Y/N");
do
{
option=upper_getchar();
if(option=='Y')
{
*book_p2=book;
*history_p2=history;
puts("录入成功");
system("pause");
}
}while(!(option=='Y'||option=='N'));
}
int main(void)
{
int i,j;
char option;
read_file();
printf(" 欢迎使用图书管理系统!\n");
Sleep(2000);
system("cls");
do
{
puts("************图书管理系统************");
puts("A.用户信息管理");
puts("B.图书信息管理");
puts("C.借书或还书");
puts("D.综合查询");
puts("E.清空数据/初始化");
puts("Q.退出");
puts("请输入选项:按回车键确认");
switch (option = upper_getchar())
{
case 'A':user_management(); write_file();break;
case 'B':book_management(); write_file();break;
case 'C':borrow_or_return_book();write_file(); break;
case 'D':query();break;
case 'E':freeall();initialization();break;
case 'Q':break;
default:puts("\n\n请输入对应操作的字母");
system("Pause");
break;
}
system("cls");
}while (option != 'Q');
freeall();
puts(" 再见,祝您生活愉快");
return 0;
}