思路
- 加载文件至链表
- 选择功能
2.1 图书录入:使用头插法链表保存 2.2 图书列表显示:循环输出链表内容 2.3 借书:输入书籍ID,学生学号。判断该书籍是否可借,(是)记录数据,该书籍库存减一;(否)重新选择功能 2.4 还书:输入书籍ID,学生学号。判断该学生是否借过此书并未归还,(是)更改归还状态,书籍库存数加一;(否)重新选择功能 2.5 借书列表显示:循环输出链表内容 2.6 书籍删除:输入书籍ID。判断该书籍是否还有借出未归还的,(是)禁止删除;(否)找到该书籍,释放当前节点
思维导图
代码
文件加载
学生模块
void load_studentfile(char *filename,struct student *st){
FILE *fp = fopen(filename,"rb+");
struct student *new_st;
new_st = (struct student*)malloc(sizeof(struct student));
if(fp == NULL) {
printf("加载文件失败\n");
return;
}
while (fread(new_st, sizeof(struct student),1,fp) != 0){
new_st->next = st->next;
st->next = new_st;
new_st = (struct student*)malloc(sizeof(struct student));
}
fclose(fp);
return;
}
书籍模块
void load_bookfile(char *filename,struct book *head){
FILE *fp = fopen(filename,"rb+");
struct book *bk;
bk = (struct book*)malloc(sizeof(struct book));
if(fp == NULL) {
printf("加载文件失败\n");
return;
}
while (fread(bk, sizeof(struct book),1,fp) != 0){
bk->next = head->next;
head->next = bk;
bk = (struct book*)malloc(sizeof(struct book));
}
fclose(fp);
return;
}
主函数
int main(int argc,char* argv[])
{
struct book head;
struct student st;
int ncmd;
char ch;
head.next = NULL;
st.next = NULL;
load_studentfile("student.bin",&st);
load_bookfile("book.bin",&head);
printf("----------------------------\n");
printf("1. 录入图书\n");
printf("2. 图书列表显示\n");
printf("3. 借书\n");
printf("4. 还书\n");
printf("5. 借书列表显示\n");
printf("6. 删除书籍\n");
printf("7. 退出\n");
printf("----------------------------\n");
scanf("%d",&ncmd);
while(ncmd != 7){
if(ncmd == 1)
{
input_book(&head);
printf("是否继续录入(Y/N)?");
ch = getchar();
while(ch == 'Y')
{
input_book(&head);
printf("是否继续录入(Y/N)?");
ch = getchar();
}
}else if(ncmd == 2){
output_book(head);
}else if(ncmd == 3){
borrow_book(&head,&st);
output_student(st);
}else if(ncmd == 4){
output_student(st);
return_book(&head,&st);
output_student(st);
}else if(ncmd == 5){
output_student(st);
}else if(ncmd == 6){
output_book(head);
del_book(&head,st);
printf("----------------------------\n");
output_book(head);
}
printf("----------------------------\n");
printf("----------------------------\n");
printf("选择功能\n");
scanf("%d",&ncmd);
}
output_book(head);
return 0;
}
图书添加
void input_book(struct book *head)
{
struct book *new_book;
new_book = (struct book*)malloc(sizeof(struct book));
printf("输入图书编号:");
scanf("%s",new_book->id);
printf("输入图书名称:");
scanf("%s",new_book->name);
printf("输入作者:");
scanf("%s",new_book->author);
printf("输入库存:");
scanf("%d",&new_book->quantity);
new_book->status = new_book->quantity;
flushall();
new_book->next = head->next;
head->next = new_book;
}
图书列表显示
void output_book(struct book head)
{
struct book *p;
FILE *pf;
pf = fopen("book.bin","w");
p = head.next;
while(p!=NULL)
{
printf("编号:%10s\t 书名:%10s\t 作者:%10s\t 存入数量:%5d\t 剩余库存:%5d\t 状态:%3s\n",
p->id,
p->name,
p->author,
p->quantity,
p->status,
p->status == 0 ? "不可借" : "可借");
fwrite(p,sizeof(struct book),1,pf);
p = p->next;
}
fclose(pf);
}
借书
判断该书籍是否还有库存可借出,可以的话记录书籍;否则输出提示
void borrow_book(struct book *head, struct student *st){
char id[10],name[128];
struct book *p;
int quantity;
struct student *new_st;
new_st = (struct student*)malloc(sizeof(struct student));
p = head->next;
printf("输入书编号:");
scanf("%s",id);
while(p != NULL){
if(strcmp(p->id,id) == 0){
if(p->status > 0){
printf("此书库存量:%d,可借!\n",p->quantity);
printf("输入借书学生学号:");
scanf("%s",new_st->number);
printf("请输入学生姓名:");
scanf("%s",new_st->name);
new_st->status = 1;
quantity = p->status;
quantity = quantity - 1;
p->status = quantity;
strcpy(new_st->bookname,p->name);
strcpy(new_st->id,p->id);
head = p;
new_st->next = st->next;
st->next = new_st;
return;
}else{
printf("此书无库存不能借出!\n");
return;
}
}
p = p->next;
head = p;
}
printf("没有此书\n");
return;
}
还书
void return_book(struct book *head, struct student *st){
char student_id[10],book_id[5];
int book_number;
struct book *p;
struct student *new_st;
new_st = st->next;
p = head->next;
printf("请输入学号:");
scanf("%s",student_id);
printf("请输入书籍id:");
scanf("%s",book_id);
while (new_st != NULL){
if(strcmp(new_st->number,student_id) == 0){
if(strcmp(new_st->id,book_id) == 0){
if(new_st->status == 1){
book_number = p->status;
p->status = book_number + 1;
new_st->status = 0;
printf("归还成功\n");
return;
} else{
printf("此学生该书以归还,无需重复操作\n");
return;
}
}else{
printf("该学生未借此书,无需归还\n");
return;
}
}
new_st = new_st->next;
st = new_st;
p = p->next;
head = p;
}
printf("该学生未借书\n");
return;
}
借书列表显示
void output_student(struct student st)
{
struct student *p;
FILE *pf;
pf = fopen("student.bin","w");
p = st.next;
while(p!=NULL)
{
printf("学号:%10s\t 名字:%10s\t 书籍编号:%10s\t 书籍名称:%10s\t 状态:%10s\n",
p->number,
p->name,
p->id,
p->bookname,
p->status == 1 ? "未还" : "已还");
fwrite(p,sizeof(struct student),1,pf);
p = p->next;
}
fclose(pf);
}
书籍删除
先判断该书籍是否有借出未归还,否 : 找到该节点,判断该节点是否为头节点(是:前节点next设为NULL,释放当前节点; 否:将当前节点的下一个节点赋给当前节点的上一个节点next,释放当前节点)
void del_book(struct book *head, struct student st){
char book_id[5];
struct book *p,*p1;
struct student *new_st;
new_st = st.next;
p = head;
p1 = head->next;
printf("请输入需要删除的书籍id:");
scanf("%s",book_id);
while (p1 != NULL){
if(strcmp(p1->id,book_id) == 0){
while(new_st != NULL){
if(strcmp(new_st->id,book_id)==0 && new_st->status==1){
printf("该书籍还有未还,暂不能删除\n");
return;
}
new_st = new_st->next;
}
if(p1->next == NULL){
p->next = NULL;
free(p1);
printf("删除书籍%s成功\n",book_id);
return;
}else{
p->next = p1->next;
free(p1);
printf("删除书籍%s成功\n",book_id);
return;
}
}
p1 = p1->next;
p = p->next;
}
printf("没有找到该书籍\n");
return;
}
效果图
代码下载地址
Github地址:https://github.com/Ltike/Learning/blob/main/BookManager.c
|