一、功能描述
设计一个图书管理程序满足图书馆基本业务需求。
二、设计要求
- 每种书的登记内容包括书号、书名、著作者、现存量和库存量等;
- 对书号建立索引表(线性表)以提高查找效率;
- 实现图书管理系统的主要功能描述。
- 用数据文件存储。
三、实现的功能
对图书信息进行增、删、改、差和查询所有
运行结果大概就是这个样子:
四、代码
Tip:主要运用的是链表和文件的读写,注释很详细。#include<stdio.h>
#include<stdlib.h>
#include "book.h"
#define len 20
#define size 20
/*
1、建立一个链表
2、将.dat文件中读出的数据放入链表中
3、进行业务操作
4、业务操作后将链表中数据存回.dat文件中
*/
//定义一个图书类型
struct oneBook
{
char isbn[size];
char bookname[size];
char author[size];
int stocknum;
float price;
int flag;
}bookarr[len];
//定义链表
typedef struct Book
{
char isbn[size];
char bookname[size];
char author[size];
int stocknum;
float price;
int flag;
struct Book* next;
} ListBook;
//定义一个输入字符,判断使用者需要的功能
char inNeed;
//编写程序首页方法
void indexPage() {
//首先写出程序的首页面
printf("|***********************************************************|\n");
printf("|---------welcome to the Library Management System----------|\n");
printf("|-------------------添加图书信息请输入1---------------------|\n");
printf("|-------------------删除图书信息请输入2---------------------|\n");
printf("|-------------------修改图书信息请输入3---------------------|\n");
printf("|-------------------查询图书信息请输入4---------------------|\n");
printf("|-------------------查询书目信息请输入5---------------------|\n");
printf("|-----------------退出图书管理系统请输入6-------------------|\n");
printf("|***********************************************************|\n");
printf("请输入要进行的操作:");
}
//编写读取文件内容的方法 ,每次用程序之前将数据从文件中读取,放入链表中
ListBook* readFile(ListBook *head) {
//定义一个指向文件的指针
FILE* fp;
char content;
ListBook* temp,*book;
//这里的r是只读的意思
if ((fp = fopen("file1.dat", "r")) == NULL) {
//打开文件失败
printf("cannot open this file\n");
exit(0);
}
//将文件中数据拿出来,方进书的结构体数组中
for (int i = 0; i < len; i++) {
fread(&bookarr[i], sizeof(struct oneBook), 1, fp);
//加一个判断跳出循环
if (bookarr[i].flag == 0) {
break;
}
//把结构体数据方进链表,success,用的是头插法
if (head == NULL) {
book = (ListBook*)malloc(sizeof(ListBook));
//字符串赋值给字符数组用strncpy
strncpy(book->isbn, bookarr[i].isbn, size);
strncpy(book->bookname, bookarr[i].bookname, size);
strncpy(book->author, bookarr[i].author, size);
book->stocknum = bookarr[i].stocknum;
book->price = bookarr[i].price;
book->flag = bookarr[i].flag;
head = book;;
head->next = NULL;
}
else {
temp = head;
book = (ListBook*)malloc(sizeof(ListBook));
strncpy(book->isbn, bookarr[i].isbn, size);
strncpy(book->bookname, bookarr[i].bookname, size);
strncpy(book->author, bookarr[i].author, size);
book->stocknum = bookarr[i].stocknum;
book->price = bookarr[i].price;
book->flag = bookarr[i].flag;
head = book;
head->next = temp;
}
}
//关闭文件输入流
fclose(fp);
return head;
}
//编写 添加图书信息方法
ListBook* insertMessage(ListBook* head) {
printf("输入想要录入的图书信息,并以#结束:\n");
printf(" *录入的模板为:ISBN码 书名 著作者 库存量 金额\n");
ListBook* book,*temp;
//把添加的数据放入链表,用的是头插法
for (int i = 0; i < len; i++) {
if (head == NULL) {
book = (ListBook*)malloc(sizeof(ListBook));
scanf("%s %s %s %d %f", &book->isbn, &book->bookname, &book->author, &book->stocknum, &book->price);
book->flag = 1;
head = book;;
head->next = NULL;
if (getchar() == '#') {
break;
}
}
else {
temp = head;
book = (ListBook*)malloc(sizeof(ListBook));
scanf("%s %s %s %d %f", &book->isbn, &book->bookname, &book->author, &book->stocknum, &book->price);
book->flag = 1;
head = book;
head->next = temp;
if (getchar() == '#') {
break;
}
}
}
//打印链表,没啥用
printf("这是刚刚添加的数据\n");
temp = head;
while (temp != NULL) {
printf("isbn:%s\t", temp->isbn);
printf("bookname:%s\t", temp->bookname);
printf("author:%s\t", temp->author);
printf("stocknum:%d\t", temp->stocknum);
printf("price:%.2f\t", temp->price);
printf("flag:%d\n", temp->flag);
temp = temp->next;
}
printf("\n添加成功!\n");
return head;
}
//编写储存数据方法, 每次程序使用结束,将数据存入文件中
void saveFile(ListBook *book) {
//先将链表中数据放回结构体数组,成功
int i = 0;
while (book != NULL) {
strncpy(bookarr[i].isbn, book->isbn, size);
strncpy(bookarr[i].bookname, book->bookname, size);
strncpy(bookarr[i].author, book->author, size);
bookarr[i].stocknum = book->stocknum;
bookarr[i].price = book->price;
bookarr[i].flag = book->flag;
book = book->next;
i++;
}
//重新写入文件
FILE* fp;
if ((fp = fopen("file1.dat", "wb")) == NULL) {
printf("cannot open file\n");
return;
}
for (int j = 0; j < i; j++) {
if (fwrite(&bookarr[j], sizeof(struct oneBook), 1, fp) != 1) {
printf("file write error\n");
}
}
fclose(fp);
printf("~程序已退出,欢迎下次使用~");
return;
}
//编写查询所有图书信息的方法
void selectAll(ListBook* book) {
ListBook* print;
print = book;
while (print != NULL) {
printf("isbn:%s\t", print->isbn);
printf("bookname:%s\t", print->bookname);
printf("author:%s\t", print->author);
printf("stocknum:%d\t", print->stocknum);
printf("price:%.2f\n", print->price);
print = print->next;
}
}
//编写删除图书信息方法
ListBook* deleteMessage(ListBook* head,char isbn[size]) {
ListBook* temp, * pre,*book;
book = temp = head;
pre = head->next;
while (head != NULL) {
//在头上
if (0 == strcmp(head->isbn, isbn)) {
head = head->next;
book = head;
free(temp);
printf("删除成功\n");
break;
}
//如果链表中只有一个值,但是不是要找的值,pre指针的strcmp会空指针
if (head->next == NULL) {
printf("没有isbn码为%s的图书\n", isbn);
break;
}
//不在头上
if (0 == strcmp(pre->isbn, isbn)) {
temp = pre;
head->next = pre->next;
free(temp);
printf("删除成功\n");
break;
}
pre = pre->next;
head = head->next;
if (head == NULL || pre == NULL) {
printf("没有isbn码为%s的图书\n", isbn);
}
}
return book;
}
//编写修改图书信息的方法
ListBook* updataMessage(ListBook* head,char isbn[size]) {
ListBook* temp;
temp = head;
//首先把要修改的图书找出来
while (head != NULL) {
if (0 == strcmp(head->isbn, isbn)) {
printf("请输入要修改的值:");
scanf("%s %s %s %d %f", &head->isbn, &head->bookname, &head->author, &head->stocknum, &head->price);
printf("修改成功");
break;
}
head = head->next;
if (head == NULL) {
printf("没有isbn码为:%s的图书\n", isbn);
}
}
return temp;
}
//编写查询图书信息方法
void selectOne(ListBook* head,char isbn[size]) {
ListBook* temp;
temp = head;
while (temp != NULL) {
//printf("打印:%s\n", temp->isbn);
if (0 == strcmp(temp->isbn, isbn)) {
printf("查询结果为:\n");
printf("isbn:%s\t", temp->isbn);
printf("bookname:%s\t", temp->bookname);
printf("author:%s\t", temp->author);
printf("stocknum:%d\t", temp->stocknum);
printf("price:%.2f\n", temp->price);
break;
}
temp = temp->next;
if (temp == NULL) {
printf("没有isbn码为:%s的图书\n", isbn);
}
}
}
void main() {
//定义一个链表
ListBook* head=NULL;
//调用程序首页方法
indexPage();
//调用读取文件内容的方法
head = readFile(head);
inNeed = getchar();
//编写一个大循环,使程序一直跑下去
while (inNeed!='6') {
if (inNeed == '1') {
head = insertMessage(head);
//输入下一步操作
printf("请输入下一步操作:\n");
//用来接收最后输入的回车符
inNeed = getchar();
//接收下一步操作的信号
inNeed = getchar();
}
else if (inNeed == '2') {
printf("请输入要删除图书的ISBN码:\n");
//调用删除方法,需要输入要删除图书的isbn
char isbn[size];
scanf("%s", isbn);
head = deleteMessage(head,isbn);
//输入下一步操作
printf("请输入下一步操作:\n");
//用来接收最后输入的回车符
inNeed = getchar();
//接收下一步操作的信号
inNeed = getchar();
}
else if (inNeed == '3') {
printf("请输入要修改的图书的ISBN码:\n");
//调用删除方法,需要输入要删除图书的isbn
char isbn[size];
scanf("%s", isbn);
head = updataMessage(head, isbn);
//输入下一步操作
printf("请输入下一步操作:\n");
//用来接收最后输入的回车符
inNeed = getchar();
//接收下一步操作的信号
inNeed = getchar();
}
else if (inNeed == '4') {
printf("请输入要查询的图书的ISBN码:\n");
//调用删除方法,需要输入要删除图书的isbn
char isbn[size];
scanf("%s", isbn);
selectOne(head, isbn);
//输入下一步操作
printf("请输入下一步操作:\n");
//用来接收最后输入的回车符
inNeed = getchar();
//接收下一步操作的信号
inNeed = getchar();
}
else if(inNeed == '5'){
printf("查询书目信息\n");
//编写查询书目方法
selectAll(head);
//输入下一步操作
printf("请输入下一步操作:\n");
//用来接收最后输入的回车符
inNeed = getchar();
//接收下一步操作的信号
inNeed = getchar();
}
}
//调用存数据方法,结束程序
saveFile(head);
return;
}
不知道是因为我自己的电脑还是vs什么的原因,第一次运行特别慢 卡,但是运行成功之后,下次运行就飞快。希望对做这个课设的小伙伴有帮助吧。
欢迎指导纠错~