图书管理系统
导读:图书管理系统基于单链表与文件交互操作,这里我就做一个较为简单的图书管理交互,即图书数量为一。
功能如下:
- 图书录入:头插法新增信息,这里设置ISBN值为唯一值,如重复则重新输入ISBN值
- 图书显示:这里全部显示、通过书号查询
- 图书修改:这里通过ISBN值进行查询是否存在
- 学生借书:输入学生学号,输入书籍ID,如已借则无法借出,如在图书馆则可以借出
- 学生还书:与借书情况相反
功能导图:
代码解析:
1、头文件引入
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define NAME_LEN 20
#define FILE_NAME "图书管理系统.txt"
2、结构体信息
typedef struct {
int ISBN; //书籍编码
int money; //价格
int student; //学生学号
char bookname[NAME_LEN + 1]; //书籍名称
char bookwrite[NAME_LEN + 1]; //书籍作者
char bookpress[NAME_LEN + 1]; //书籍出版社
char bookcategory[NAME_LEN + 1];//书籍类科
char bookloan[5]; //是否借出
} Bookmanage; //用于存储单个学生的信息
typedef struct node {
Bookmanage book; //数据域,存储图书信息
struct node *next; //指针域,指向下一个节点
} BookmanageNode; //图书节点
typedef struct {
BookmanageNode *head; //头指针
BookmanageNode *tail; //尾指针
int count; //图书节点总数
} bookList;
3、函数声明
void first_main();
void initialize(bookList *L);//初始化链表,创建头节点
void enter(bookList *L); //录入链表
void display(bookList *L); //输出链表
void find(bookList *L); //查找某节点
void modify(bookList *L); //修改某节点
void sort(bookList *L); //降序重新建表并输出
void write(bookList *L); //写入文件,边写边释放空间
void read(bookList *L); //读取文件,边读边建表
void Books_Borrow(bookList *L);
void Books_Return(bookList *L);
int check(bookList *L);
4、创建头结点
void initialize(bookList *L) {
//创建头节点
BookmanageNode *b = (BookmanageNode *)malloc(sizeof(BookmanageNode));
b->next = NULL;
//初始化链表:
//头尾指针均指向头节点,初始长度为零
L->head = b;
L->tail = b;
L->count = 0;
}
。。。。。。
功能介绍
1、主页面
2、录入
。。。。。。
附上代码:
/*
图书管理系统
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define NAME_LEN 20
#define FILE_NAME "图书管理系统.txt"
typedef struct {
int ISBN; //书籍编码
int money; //价格
int student; //学生学号
char bookname[NAME_LEN + 1]; //书籍名称
char bookwrite[NAME_LEN + 1]; //书籍作者
char bookpress[NAME_LEN + 1]; //书籍出版社
char bookcategory[NAME_LEN + 1];//书籍类科
char bookloan[5]; //是否借出
} Bookmanage; //用于存储单个学生的信息
typedef struct node {
Bookmanage book; //数据域,存储图书信息
struct node *next; //指针域,指向下一个节点
} BookmanageNode; //图书节点
typedef struct {
BookmanageNode *head; //头指针
BookmanageNode *tail; //尾指针
int count; //图书节点总数
} bookList; //图书链表
void first_main();
void initialize(bookList *L);//初始化链表,创建头节点
void enter(bookList *L); //录入链表
void display(bookList *L); //输出链表
void find(bookList *L); //查找某节点
void modify(bookList *L); //修改某节点
void sort(bookList *L); //降序重新建表并输出
void write(bookList *L); //写入文件,边写边释放空间
void read(bookList *L); //读取文件,边读边建表
void Books_Borrow(bookList *L);
void Books_Return(bookList *L);
int check(bookList *L);
void first_main(){
//互动界面
printf(" **************图书信息管理系统**************\n");
printf(" * 1.录入新的书籍信息 *\n");
printf(" * 2.按编码修改书籍信息 *\n");
printf(" * 3.按编码查询书籍信息 *\n");
printf(" * 4.输出全部书籍的信息 *\n");
printf(" * 5.学生借书 *\n");
printf(" * 6.学生还书 *\n");
printf(" * 0.退出并保存管理系统 *\n");
printf(" ********************************************\n");
printf(" \n");
}
int main() {
//创建图书链表
bookList *L = (bookList *)malloc(sizeof(bookList));
//初始化图书链表
initialize(L);
//从文件里读取数据到链表
read(L);
//互动界面是用一个无限循环和一个switch写的
while (1) {
first_main();
int select;
printf("请输入您的选择: ");
scanf("%d", &select);
system("cls");
switch (select) {
case 1:
enter(L);
break;
case 2:
modify(L);
break;
case 3:
find(L);
break;
case 4:
display(L);
break;
case 5:
Books_Borrow(L);
break;
case 6:
Books_Return(L);
break;
case 0:
write(L);
free(L->head); //头节点被销毁
free(L); //链表被销毁
return 0;
default:
printf("%d是无效的数字,请重新输入!\n\n", select);
break;
}
}
return 0;
}
void initialize(bookList *L) {
//创建头节点
BookmanageNode *b = (BookmanageNode *)malloc(sizeof(BookmanageNode));
b->next = NULL;
//初始化链表:
//头尾指针均指向头节点,初始长度为零
L->head = b;
L->tail = b;
L->count = 0;
}
int check(bookList *L){//查询是否相同
int isbn;
while(1){
int k = 0,flag = 1;
int ISBN[NAME_LEN];
printf("请输入书籍编码:");
scanf("%d", &isbn);
BookmanageNode *b;
b = L->head;
while (b->next) {
b = b->next;
ISBN[k++] = b->book.ISBN;
}
for(int i=0;i<k;i++){
if(ISBN[i] == isbn){
flag = 0;
break;
}
}
if(L->count<1||flag == 1)break;
printf("书籍编码已存在请重新输入!\n");
}
return isbn;
}
void enter(bookList *L) {
int ISBN;
//创建新节点
BookmanageNode *b = (BookmanageNode *)malloc(sizeof(BookmanageNode));
//键入信息并存到新节点中
printf("请输入书籍名称:");
scanf("%s", b->book.bookname);
ISBN = check(L);
b->book.ISBN = ISBN;
printf("请输入书籍作者:");
scanf("%s", b->book.bookwrite);
printf("请输入书籍出版社:");
scanf("%s", b->book.bookpress);
printf("请输入书籍类科:");
scanf("%s", b->book.bookcategory);
printf("请输入书籍价格:");
scanf("%d", &b->book.money);
strcpy(b->book.bookloan,"可借");
b->book.student = 0;
//若链表为空,将尾指针指向新节点
if (L->head == L->tail) {
L->tail = b;
}
//将新节点插进链表头部(头插法)
b->next = L->head->next;
L->head->next = b;
L->count++;
//输出互动信息
printf("信息录入成功!\n\n");
}
void display(bookList *L) {
printf("共有%d本图书数据:\n", L->count);
printf("书名\t\t\t编码\t\t学生\t\t作者\t\t出版社\t\t类科\t价格\t是否借出\n");
//创建一节点指针指向头节点
BookmanageNode *b;
b = L->head;
//遍历链表输出
while (b->next) {
b = b->next;
printf("%s", b->book.bookname);
printf("\t\t%d", b->book.ISBN);
printf("\t\t%d", b->book.student);
printf("\t\t%s", b->book.bookwrite);
printf("\t\t%s", b->book.bookpress);
printf("\t%s", b->book.bookcategory);
printf("\t%d", b->book.money);
printf("\t%s", b->book.bookloan);
printf("\n");
}
printf("\n");
}
void find(bookList *L) {
//让用户输入要查找的书籍
printf("请输入书籍编码:");
int isbn;
scanf("%d", &isbn);
//遍历链表对比名字
BookmanageNode *b = L->head->next;
while (b) {
//符合了就输出并结束函数
if (b->book.ISBN == isbn) {
printf("书名\t\t\t编码\t\t学生\t\t作者\t\t出版社\t\t类科\t价格\t是否借出\n");
printf("%s", b->book.bookname);
printf("\t\t%d", b->book.ISBN);
printf("\t\t%d", b->book.student);
printf("\t\t%s", b->book.bookwrite);
printf("\t\t%s", b->book.bookpress);
printf("\t%s", b->book.bookcategory);
printf("\t%d", b->book.money);
printf("\t%s", b->book.bookloan);
printf("\n\n");
return;
}
//名字不符合就下一个
b = b->next;
}
//遍历完里都没找到这个名字
printf("没找到这个%d的信息!\n\n", isbn);
}
void modify(bookList *L) {
//让用户输入要修改的书籍
printf("请输入书籍编码:");
int isbn,ISBN;
scanf("%d", &isbn);
//遍历链表对比名字
BookmanageNode *b = L->head->next;
while (b) {
//符合了就让用户重新键入并结束函数
if (b->book.ISBN == isbn) {
printf("请重新输入信息:\n");
printf("请输入书籍名称:");
scanf("%s", b->book.bookname);
ISBN = check(L);
b->book.ISBN = ISBN;
printf("请输入书籍作者:");
scanf("%s", b->book.bookwrite);
printf("请输入书籍出版社:");
scanf("%s", b->book.bookpress);
printf("请输入书籍类科:");
scanf("%s", b->book.bookcategory);
printf("请输入书籍价格:");
scanf("%d", &b->book.money);
printf("请输入书籍是否借出:");
scanf("%s", b->book.bookloan);
printf("信息修改成功!\n\n");
return;
}
//名字不符合就下一个
b = b->next;
}
//遍历完里都没找到
printf("没找到这个%d的信息!\n\n", isbn);
}
void Books_Borrow(bookList *L) {
//学生借阅书籍
printf("请输入学号(7位以内):");
int studentID;
int isbn;
scanf("%d", &studentID);
printf("请输入书号:");
scanf("%d",&isbn);
//遍历链表对比名字
BookmanageNode *b = L->head->next;
while (b) {
//符合了就让用户重新键入并结束函数
if (b->book.ISBN == isbn) {
if(strcmp(b->book.bookloan,"可借")==0) {
b->book.student=studentID;
strcpy(b->book.bookloan,"借出");
printf("图书借出成功!\n");
}
else if(b->book.bookloan != "可借") {
printf("图书借出失败!\n");
}
return;
}
//名字不符合就下一个
b = b->next;
}
//遍历完里都没找到
printf("没找到这个%d的信息!\n\n", isbn);
}
void Books_Return(bookList *L) {
//学生借阅书籍
printf("请输入学号(7位以内):");
int studentID;
int isbn;
scanf("%d", &studentID);
printf("请输入书号:");
scanf("%d",&isbn);
//遍历链表对比名字
BookmanageNode *b = L->head->next;
while (b) {
//符合了就让用户重新键入并结束函数
if (b->book.ISBN == isbn) {
if(strcmp(b->book.bookloan,"借出")==0) {
b->book.student=studentID;
strcpy(b->book.bookloan,"可借");
printf("图书归还成功!\n");
}
else if(b->book.bookloan != "借出") {
printf("图书归还失败!\n");
}
return;
}
//名字不符合就下一个
b = b->next;
}
//遍历完里都没找到
printf("没找到这个%d的信息!\n\n", isbn);
}
void write(bookList *L) {
//打开文件流
FILE *fp = fopen(FILE_NAME, "w");
if (fp == NULL) {
printf("文件%s打开失败\n", FILE_NAME);
exit(EXIT_FAILURE);
}
//将学生节点总数输出在第一行
fprintf(fp, "%d\n", L->count);
//创建一节点指针指向头节点
BookmanageNode *b;
b = L->head->next;
//遍历链表,一组数据作为一行输出
while (b) {
fprintf(fp, "%s ", b->book.bookname);
fprintf(fp, "%d ", b->book.student);
fprintf(fp, "%d ", b->book.ISBN);
fprintf(fp, "%s ", b->book.bookwrite);
fprintf(fp, "%s ", b->book.bookpress);
fprintf(fp, "%s ", b->book.bookcategory);
fprintf(fp, "%d ", b->book.money);
fprintf(fp, "%s ", b->book.bookloan);
fprintf(fp, "\n");
//输出完成之后释放节点空间
BookmanageNode *next = b->next;
free(b);
b = next;
}
//关闭文件流
fclose(fp);
//互动信息
printf("数据已保存!谢谢使用,再见!\n");
}
void read(bookList *L) {
//打开文件流
FILE *fp = fopen(FILE_NAME, "r");
if (fp == NULL) {
printf("文件%s打开失败\n", FILE_NAME);
printf("文件%s正在创建,请稍后\n", FILE_NAME);
fp = fopen(FILE_NAME, "w");
Sleep(1000);
printf("文件%s创建成功\n", FILE_NAME);
}
//读取第一行的学生节点总数
fscanf(fp, "%d", &L->count);
//循环读取数据,循环次数为count
for (int i = 1; i <= L->count; i++) {
//创建新节点
BookmanageNode *b = (BookmanageNode *)malloc(sizeof(BookmanageNode));
//读取数据
fscanf(fp, "%s ", b->book.bookname);
fscanf(fp, "%d ", &b->book.student);
fscanf(fp, "%d ", &b->book.ISBN);
fscanf(fp, "%s ", b->book.bookwrite);
fscanf(fp, "%s ", b->book.bookpress);
fscanf(fp, "%s ", b->book.bookcategory);
fscanf(fp, "%d ", &b->book.money);
fscanf(fp, "%s ", b->book.bookloan);
//将新节点插进链表尾部(尾插法)
b->next = NULL;
L->tail->next = b;
L->tail = b;
}
//关闭文件流
fclose(fp);
}
附:代码可能存在不完善,望各位大神给出意见。感谢