基于C语言实现的图书管理系统链表版+文件【加背景乐】

项目是大一的课设,后面就没去改了,如果有什么错误的,有不足的,没完善的,还请自己稍微改一改,往上增加代码,也能增强自己的代码能力。

book.cpp

#include<stdio.h>
//#include <graphics.h>//ege图形库 
#include<string.h>
#include<stdlib.h>
#include<windows.h>
#include<sys/time.h>
#include<mmsystem.h>//导入声音头文件
#pragma comment(lib,"Winmm.lib")
#include<conio.h>
#include "book.h"
int main(){
	system("color f0"); //白底黑字 
	int l,M;
	char answer;
	Linkbook B;
	printf("先生/女士,是否需要音乐?---y/n\n------");
	answer=getchar();
	if(answer=='Y'||answer=='y')
	{
		printf("##############点歌#############\n");
		printf("\t1.<<星星在唱歌>>\t#\n");
		printf("\t2.<<银河与星斗>>\t#\n");
		printf("\t3.<<这里是神奇的赛尔号>>#\n");
		printf("请选择:");
		scanf("%d",&M);
		if(M==1)
		{
			PlaySound("星星在唱歌.wav",NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);
			printf("真有眼光呢!\n");
			getch();
		}
		else if(M==2)
		{
			PlaySound("D:\\吴嘉怡 - 银河与星斗 (女生治愈版).wav",NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);
			printf("真有眼光呢!\n");
			getch();
		}
		else if(M==3){
			PlaySound("D:\\张杰 - 这里是神奇的赛尔号.wav",NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);
			printf("真有眼光呢!\n");
			getch();
		}
		else{
			printf("客户选择不放音乐。\n");
			getch();
		}
	}
	else{
			printf("客户选择不放音乐。。\n");
			getch();
		}
	if(init(B)) { //初始化
		menu(B);//调用菜单函数
	} else {
	//	system("color 4");//字体红色 
		printf("图书链表初始化有误!\n");
	}
}

void menu(Linkbook &B) {//菜单 
	int l;
	do { //do-while循环实现重复选择
		system("cls");//清屏,使程序相对干净
		system("color f0"); //白底黑字 
		readbook(B);//读取文件的书籍信息
		time_t t;
	    struct tm *lt;
	    time (&t);//获取Unix时间戳。
	    lt=localtime (&t);//转为时间结构。
	    printf("\t\t现在是北京时间: %d/%d/%d %2d:%02d:%02d\n",lt->tm_year+1900,lt->tm_mon+1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec);//输出结果
		printf("\t\t_________________________________________\n");
		printf("\t\t|##############图书管理系统##############|\n");
		printf("\t\t|############程序完成者:杨继乐###########|\n");
		printf("\t\t|#\t\t1.增加书籍\t\t#|\n");
		printf("\t\t|#\t\t2.删除书籍\t\t#|\n");
		printf("\t\t|#\t\t3.修改书籍信息\t\t#|\n");
		printf("\t\t|#\t\t4.查看书籍信息\t\t#|\n");
		printf("\t\t|#\t\t5.展示所有书籍\t\t#|\n");
		printf("\t\t|#\t\t6.查询书籍总量\t\t#|\n");
		printf("\t\t|#\t\t7.按照书籍库存排序\t#|\n");
		printf("\t\t|#\t\t8.借阅书籍办理\t\t#|\n");
		printf("\t\t|#\t\t9.归还书籍办理\t\t#|\n");
		printf("\t\t|#\t\t10.购买书籍\t\t#|\n");
		printf("\t\t|#\t\t11.读书路漫漫\t\t#|\n");
		printf("\t\t|#\t\t0.退出系统\t\t#|\n");
		printf("\t\t-----------------------------------------\n");
		printf("请选择:");
		scanf("%d",&l);
		if(l==0) {
//			char str[]="18296309013";
//			printf("%d\n",sizeof(str));
//			for(int i=0;i<11;i++)
//			{
//				printf("%s ",&str); 
//			}
			printf("#########程序已退出,谢谢使用本系统########\n");
			exit(0);
		} else if(l==1) {
			add(B);
			getchar();//吸收回车符
			getchar();//与system("cls")搭配
		} else if(l==2) {
			dele_book(B);
			getchar();
			getchar();
		} else if(l==3) {
			revise(B);
			getchar();
			getchar();
		} else if(l==4) {
			search(B);
			getchar();
			//getchar();
		} else if(l==5) {
			show(B);
			getchar();
			getchar();
		} else if(l==6) {
			printf("图书共有%d本\n",num_book(B));
			getchar();
			getchar();
		} else if(l==7) {
			sorted(B);
			Linkbook s=B->next;
			printf("按照库存量排序如下:\n");
			printf("书号\t书名\t作者\t书库\t库存\t现存量\n");
			while(s) {
				printf("%s\t%s\t%s\t%s\t%d\t%d\n",s->id,s->name,s->writer,s->library,s->stock,s->extant);
				s=s->next;
			}
			getchar();
			getchar();
		} else if(l==8) {
			lend(B);
			getchar();
			getchar();
		} else if(l==9) {
			revert(B);
			getchar();
			getchar();
		} else if(l==10){
			Buy_book(B);
			getchar();
			getchar();
		} 
		else if(l==11)
		{
			grah_book();
		}
		else {
			//system("color 4");
			printf("输入数字有误!\n");
		}
		savebook(B);//进行一次操作就保存一次 
	} while(1);
}

int init(Linkbook &B){
	B=(Listbook*)malloc(sizeof(Listbook));//申请一个结点 
	B->next=NULL;//初始化一个带有头结点的链表 
	if(B!=NULL) {
		return 1;
	} else {
		return 0;
	}
}

/*给书籍编号
利用随机数 自动编号*/
void number(Linkbook &L,Linkbook B) {
	srand(time(0));//随机种子 
	Linkbook p=B->next;
	char letter[10]="ABCDEFGH";//字母随机 
	char num[10]="12345678";//数字随机 
	char str[5];
	int random_1,random_2,random_3,random_4;
	int flag=1;
	//编号组成为开头大写字母后接三位数字,如 D218
	while(flag==1){
		flag=0;
		Linkbook p=B->next;
		memset(str,0,sizeof(str));//清空字符串 
		//生成0-7的随机数
		random_1=rand()%8;//生成[m,n]的随机数,用rand()%(n-m+1)+m
		random_2=rand()%8;
		random_3=rand()%8;
		random_4=rand()%8;
		str[0]=letter[random_1];
		str[1]=num[random_2];
		str[2]=num[random_3];
		str[3]=num[random_4];
		while(p)
		{
			if(strcmp(p->id,str)==0)//判断生成编号是否与已编号的书籍的编号重复
			{
				flag=1;
			}
			p=p->next;
		}
//		Linkbook p=B->next;
//		while(strcmp(p->id,str)==0){//判断生成编号是否与已编号的书籍的编号重复
//			random_1=rand()%8;
//			random_2=rand()%8;
//			random_3=rand()%8;
//			random_4=rand()%8;
//			str[0]=letter[random_1];
//			str[1]=num[random_2];
//			str[2]=num[random_3];
//			str[3]=num[random_4];
//		}	
	}
	strcpy(L->id,str);//复制编号到链表上
	//system("color 2");
	printf("此书籍的编号为:%s\n",str);
}

void add(Linkbook &B) {
	Linkbook p=B;
	while(p->next){//指向最后一个非空结点 
		p=p->next;
	}
	Linkbook q=(Listbook*)malloc(sizeof(Listbook));//申请一个结点存入信息 
	printf("请输入书籍相关信息:\n");
	printf("书名\t作者\t书库\t库存量\t现存量\n");
	scanf("%s\t%s\t%s\t%d\t%d",&(q->name),&(q->writer),&(q->library),&(q->stock),&(q->extant));
	number(q,B);
	q->e=0;	
	q->next=NULL; //将下一个结点置空 
	p->next=q;//结点连接 
//	system("color 2");
	printf("增加成功!\n");
}

void dele_book(Linkbook &B)//删除书籍
{
	char book[20],choice;
	int t=0;
	Linkbook p=(Listbook*)malloc(sizeof(Listbook));//申请两个结点用于等会删除使用 
	Linkbook q=(Listbook*)malloc(sizeof(Listbook));
	p=B;
	q=p->next;
	printf("请输人想要删除的图书的书名:");
	scanf("%s",&book);
	while(q){//遍历结点 
		if(strcmp(q->name,book)==0) {//寻找是否有需要删除的结点 
			t=1;
			//system("color 2");
			printf("确认删除?------Y(y)/N(n):");//确认是否需要删除 
			if((choice=getchar())=='Y'||(choice=getchar())=='y') {
				p->next=q->next;
				free(q);//释放结点 
				printf("删除成功!\n");
			}else{
				printf("取消删除成功!\n");
			}
			break;
		}
		p=q;
		q=q->next;//指向下一个结点 
	}
	if(t==0) {
		//system("color 4");
		printf("没有查找到此书的信息!\n");
	}
}

void revise(Linkbook &B) {//修改图书 
	char book[20],choice;
	int t=0,l;
	Linkbook p=B->next;
//	Linkbook q=(Listbook*)malloc(sizeof(Listbook));
//	q=p->next;
	printf("请输入想要修改的图书的书名:");
	scanf("%s",&book);
	while(p){//遍历结点 
		if(strcmp(p->name,book)==0){
			t=1;//如果t=1代表存在此书籍
			for(;;) {//for循环可以一直修改 
				printf("要修改的书籍信息如下:\n");
				printf("书号\t书名\t作者\t书库\t库存量\t现存量\n");
				printf("%s\t%s\t%s\t%s\t%d\t%d\n\n",p->id,p->name,p->writer,p->library,p->stock,p->extant);
				printf("1.修改书号\n");
				printf("2.修改书名\n");
				printf("3.修改书籍作者\n");
				printf("4.修改书籍书库\n");
				printf("5.修改书籍库存量\n");
				printf("6.修改书籍现存量\n");
				printf("0.返回主菜单\n");
				printf("请选择(0-6):");
				scanf("%d",&l);
				if(l==0){
					printf("正在保存修改数据!\n");
					int flag=30;
					while(flag--) { 
									printf("▅ ");//进度条 
									Sleep(2);//休眠 
								}
					printf("保存成功!\n");
					break;//退出for循环
				} else if(l==1) {
					printf("修改为:");
					scanf("%s",&(p->id));
				} else if(l==2) {
					printf("修改为:");
					scanf("%s",&(p->name));
				} else if(l==3) {
					printf("修改为:");
					scanf("%s",&(p->writer));
				} else if(l==4) {
					printf("修改为:");
					scanf("%s",&(p->library));
				} else if(l==5) {
					printf("修改为:");
					scanf("%d",&(p->stock));
				} else if(l==6) {
					printf("修改为:");
					scanf("%d",&(p->extant));
				} else {
					printf("输入数字有误!\n");
				}
			}
			break;//退出while循环
		}
		p=p->next;//指向下一个结点 
	}
	if(t==0) {
		//system("color 4");
		printf("没有查询到此书籍!\n");
	}
}

void search(Linkbook B) {
	Linkbook p=B->next;
	char str[20];
	int t=0;
	printf("请输入需要查询的书籍:");
	getchar();
	gets(str);//输入字符串 
	while(p) {//遍历结点 
		if(strcmp(p->name,str)==0) {//判断是否有此结点 
			//system("color 2");
			printf("书号\t书名\t作者\t书库\t库存\t现存量\n");
			printf("%s\t%s\t%s\t%s\t%d\t%d\n",p->id,p->name,p->writer,p->library,p->stock,p->extant);
			t=1;
			break;
		}
		p=p->next;
	}
	if(t==0){
		//system("color 4");
		printf("查无此书籍!\n");//提示 
	}
}

void sorted(Linkbook &B) {//按照库存降序排序 
	int i,count=0,num;//count记录链表结点的个数,num进行内层循环,
	Linkbook p,q,tail;//创建三个指针,进行冒泡排序
	p=B;
	while(p->next!=NULL) { //计算出结点的个数
		count++;
		p=p->next;
	}
	for(i=0; i<count-1; i++) { //外层循环,跟数组冒泡排序一样
		num=count-i-1;//记录内层循环需要的次数,跟数组冒泡排序一样,
		q=B->next;//令q指向第一个结点
		p=q->next;//令p指向后一个结点
		tail=B;//让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作
		while(num--) { //内层循环 次数跟数组冒泡排序一样
			if(q->stock<p->stock) { //如果该结点的值大于后一个结点,则交换
				q->next=p->next;
				p->next=q;
				tail->next=p;
			}
			tail=tail->next;
			q=tail->next;
			p=q->next;
		}
	}
}

int exam_phone(char phone[]){ //检验手机号是否规范
	int l=strlen(phone);//计算字符串长度 
	if(l!=11) {//不等于11就return 0
		return 0;
	}
	for(int i=0; i<11; i++) {
		if(phone[i]<'0'||phone[i]>'9'){//有一个不为数字就return 0 
			return 0;
		}
	}
	return 1;
}

int num_book(Linkbook B){
	Linkbook p=B->next;
	int k=0;
	while(p) {//遍历结点 
		k+=p->extant+p->stock;//将库存量和现存量都加起来 
		p=p->next;
	}
	return k;//返回总数 
}

void show(Linkbook B){//显示所有书籍
	Linkbook p=B->next;
//	system("color 2");
	printf("书号\t书名\t作者\t书库\t库存\t现存量\n");//打印开头 
	while(p) {//遍历结点 
		printf("%s\t%s\t%s\t%s\t%d\t%d\n",p->id,p->name,p->writer,p->library,p->stock,p->extant);
		p=p->next;
	}
}

void lend(Linkbook &B){ //借书
	Linkbook p=B->next;
	char str[20],phone[20];
	int t=0;
	printf("**********借书办理***********\n");//打印开头 
	printf("/*\t提示:\n");
	printf("**********请输入需要借阅的书籍名称:");
	getchar();
	gets(str);
	printf("正在查询中 ");
	while(p){//遍历结点 
		int flag=30;
		if(strcmp(p->name,str)==0){//用strcmp判断字符串是否相等 
			t=1;
			if(p->stock==0) {
				//system("color 4");
				printf("存在此书籍,但库存量不足!\n");
				break;
			}
			while(flag--){ //加载
				printf("▅ ");
				Sleep(2);//休眠
			}
			printf("\n存在此书籍!\n");
			printf("**********温馨提示:号码组成为11为数字***********\n");
			printf("**********请留下您的手机号码:");
			gets(phone);
			while(exam_phone(phone)==0) {//检验手机号 
				//system("color 4");
				printf("手机号格式不对\n");
				printf("请重新输入手机号:");
				gets(phone);
			}
			strcpy(p->phone[p->e],phone);//将借阅人电话复制在链表信息上 
			p->e++;
			time_t t;
		    struct tm *lt;
		    time (&t);//获取Unix时间戳。
		    lt=localtime (&t);//转为时间结构。
		//	system("color 2");
			printf("借阅成功!\n");
			printf("请于 %d-%d-%d %2d:%02d:%02d 之前归还\n",lt->tm_year+1900,lt->tm_mon+1,lt->tm_mday+10,lt->tm_hour,lt->tm_min,lt->tm_sec);//有点问题 
			break;
		}
		p=p->next;
	}
	if(t==0) {
		//system("color 4");
		printf("暂无此书籍\n");
	}

}

void revert(Linkbook &B){ //还书
	Linkbook p=B->next;
	char str[20],phone[20];
	int t=0,i,j;
	printf("\n**********还书办理***********\n");
	printf("请输入需要归还的书籍名称或者书号:");
	getchar();//吸收换行符 
	gets(str);
	while(p) {//遍历结点 
		if((strcmp(p->name,str)==0)||strcmp(p->id,str)==0) {
			t=1;
			if(p->e==0) {
				//system("color 4");
				printf("暂无借阅人,请检查书名或书号!\n");
				getchar();
				break;
			}
			for(i=0; i<p->e; i++) {//打印所有借阅人 
				//system("color 2");
				printf("借阅人%d: %s\n",i+1,p->phone[i]);
			}
			getchar();
			printf("请输入借阅人后面的数字:");
			scanf("%d",&j);
			while(j>p->e||j<0) {
			//	system("color 4");
				printf("输入数字有误!\n");
				printf("请重新输入:");
				scanf("%d",&j);
			}
			for(i=j-1; i<p->e; i++) {
				strcpy(p->phone[i],p->phone[i+1]);
			}//将借阅人电话删除 
			p->e--;
			//system("color 2");
			printf("归还成功\n");
		}
		p=p->next;
	}
	if(t==0)
	{
		//system("color 4");
		printf("没有此书籍!\n");
	}
}

void Buy_book(Linkbook &B)//购买书籍 
{
	srand(time(0));
	Linkbook p=(Listbook*)malloc(sizeof(Listbook));
	char str[20];
	int t=0,buy;
	printf("********购买书籍*********\n");
	printf("请输入书名:");
	getchar();
	gets(str);
	for(p=B->next;p!=NULL;p=p->next)//利用for循环寻找图书 
	{
		if(strcmp(str,p->name)==0)
		{
		//	system("color 2");
			t=1;
			int price=rand()%(80-20+1)+20;
			printf("此书籍在%s 书库!\n",p->library);
			printf("书籍 %s 的价格为 %d元\n",str,price);
			printf("请输入金额进行购买:");
			scanf("%d",&buy);
			if(buy>=price)
			{
				printf("成功支付%d 元,找您 %d元\n",buy,buy-price);
				printf("欢迎下次购买!\n");
				p->stock--;//库存-- 
			}
			else{
				while(buy<price)
				{
					printf("支付金额不足,请重新支付\n");
					printf("请输入金额:");
					scanf("%d",&buy);
				}
				printf("成功支付%d 元,找您 %d元\n",buy,buy-price);
				printf("欢迎下次购买!\n");
				p->stock--;
			} 
			break;
		}
	}
	if(t==0)
	{
	//	system("color 4");
		printf("没有您想要购买的书籍!\n");
	} 
}

void grah_book()
{
	system("ege.exe");
} 

void readbook(Linkbook &B) { //读取文件
	Linkbook p=B;
	Linkbook s=(Listbook*)malloc(sizeof(Listbook));//申请一个结点 
	FILE *fp,*fp1;//两个文本,定义两个文本指针 
	fp=fopen("book.txt","r");//以读的方式打开图书信息文件
	fp1=fopen("lender.txt","r");//以读的方式打开借阅信息文件
	if(fp==NULL||fp1==NULL){
		//system("color 4");
		printf("文件打开失败!\n");
	} 
	
	else{
		char id[20],name[20],writer[20],library[20],phone[20][20];
		int stock,extant,e;
		while(fscanf(fp,"%s\t%s\t%s\t%s\t%d\t%d\t%d\n",&id,&name,&writer,&library,&stock,&extant,&e)==7) {
			Linkbook q=(Listbook*)malloc(sizeof(Listbook));
			//printf("%s\t%s\t%s\t%s\t%d\t%d\t%d\n",id,name,writer,library,stock,extant,e);
			for(int i=0;i<e;i++)
			{
				fscanf(fp1,"%s\t",&phone[i]); 
			}
			fscanf(fp1,"\n");
			strcpy(q->id,id);strcpy(q->name,name);strcpy(q->writer,writer);strcpy(q->library,library);
			q->stock=stock;q->extant=extant;q->e=e;
			for(int i=0;i<e;i++)
			{
				strcpy(q->phone[i],phone[i]); 
			}
			p->next=q;
			p=q;
		}
		p->next=NULL;
	}
	fclose(fp);//关闭文件,以防泄露
	fclose(fp1);
}

void savebook(Linkbook &B){
	FILE *fp,*fp1 ;//创建两个文本指针 
	Linkbook p=B->next;
	fp=fopen("book.txt","w+");//以写的方式打开文本 
	fp1=fopen("lender.txt","w+");
	if(fp==NULL||fp1==NULL) {
		//system("color 4");
		printf("文件创建失败");
		return;
	} else{
		while(p){//遍历链表 
			fprintf(fp,"%s\t%s\t%s\t%s\t%d\t%d\t%d\n",p->id,p->name,p->writer,p->library,p->stock,p->extant,p->e);
			for(int i=0;i<p->e;i++)
			{
				fprintf(fp1,"%s\t",p->phone[i]);
			}
			fprintf(fp1,"\n");
			p=p->next;
		}
		fclose(fp);//关闭文件 
		fclose(fp1);
	}
}








book.h

typedef struct Book{ 
	char id[20];//书号  
	char name[20];//书名 
	char writer[20];//作者 
	char library[20];//书库  
	int stock;//库存量 
	int extant;//现存量 
	char phone[20][20];//借阅者手机号 
	int e;//借阅者数量  
	struct Book *next;
}Listbook,*Linkbook;
void menu(Linkbook &B);//菜单
int init(Linkbook &B);//初始化链表
void number(Linkbook &L,Linkbook B);//给书籍编号 
int num_book(Linkbook B);//求书的总量 
void add(Linkbook &B); //增加书籍 
void dele_book(Linkbook &B);//删除书籍 
void revise(Linkbook &B);//修改书籍信息 
void search(Linkbook B);//查看书籍信息 
void lend(Linkbook &B);//借书
void revert(Linkbook &B);//还书
void sorted(Linkbook &B);//排序
void show(Linkbook B);//展示有库存的书籍 
int exam_phone(char phone[]);//检验手机号是否规范 
void Buy_book(Linkbook &B);//购买书籍 
void grah_book();//书籍图片 
void readbook(Linkbook &B);//从文件中读取书籍信息
void savebook(Linkbook &B);//将书籍信息保存

其他文件:

book.txt、lender.txt。存放在源码的同级目录下。

背景音乐也一样放在同级目录,必须是.wav后缀的背景音乐,可以下载音乐后直接修改后缀名,也可以去网上转文件类型。背景音乐加了之后要在代码里面改成自己的音乐名称。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值