python设计一个图书管理的简单程序用单链表_轻松学做C语言课程设计(图书管理系统-链表实现...)
题外话
C语言课程设计,对于初学者来说,主要是综合运用C语言基础知识,以实际项目的形式锻炼编程能力。从今天开始,一起轻松学做C语言课程设计常见项目,建议先运行代码,再一步步理解其实现。
题目要求
图书管理系统提供图书信息管理以及借还管理。图书信息至少包括:图书编号、书名、价格、作者、借还状态,提供以下功能:
1.增加图书信息,录入;
2.查询已有的所有图书信息;
3.删除图书;
4.修改图书信息;
5.借阅图书;
6.归还图书;
7.退出;
实现要点
该要求较为简单,可采用结构数组或链表实现,本文采用链表实现;
使用文件保存图书信息;
图书借还状态使用整数保存,1表示已还,0表示借出;
备注:初学者掌握数组、链表、文件这几种方式即可,对于计算机专业,学过数据结构课程的学生,还可以用二叉树等方式实现更多功能。
数组实现:参见上一篇文章。
其实做为一个学习者,有一个学习的氛围跟一个交流圈子特别重要这里我推荐一个C/C++基础交流583650410,不管你是小白还是转行人士欢迎入驻,大家一起交流成长。
编程环境
采用Dev-C++集成开发环境;
涉及C语言知识点:结构、数组、枚举、函数、文件读写;
源代码
*/
#include
#include
#include
// 书名最大长度
#define NAME_LEN 60
// 作者姓名最大长度
#define AUTHOR_LEN 60
// 文件名
#define BOOK_FILE "books.txt"
// 定义书本信息结构体
typedef struct book{
// 编号
int id;
// 书名
char name[NAME_LEN];
// 价格
double price;
// 作者
char author[AUTHOR_LEN];
// 借出状态,1表示借出,0表示未借出
int state;
}BOOK;
// 定义链表结点结构类型
struct node
{
BOOK book;
struct node* next;
};
/*
定义功能函数,实现图书信息的增加、删除、修改、查阅、借还等功能。
这里使用链表实现
*/
// 显示功能菜单
void showMenu(struct node *head);
// 添加图书信息 传递链表头结点指针
void addBook(struct node *head);
// 查看所有图书信息
void queryBook(struct node *head);
// 根据图书ID删除图书信息
void deleteBook(struct node *head);
// 根据图书ID修改图书信息
void updateBook(struct node *head);
// 借书
void borrowBook(struct node *head);
// 还书
void returnBook(struct node *head);
// 定义链表基础功能函数
struct node* createBookNode(BOOK *book);
struct node* insertBookNode(struct node* head, BOOK *book);
struct node* createBookList();
void freeBookList(struct node* head);
struct node* queryBookListById(struct node* head, int id);
int deleteBookListById(struct node* head, int id);
int getBookListLength(struct node* head);
void printBookListInfo(struct node* head);
void saveBookListToFile(struct node* head);
void readBookListFromFile(struct node* head);
void error(const char* err);
int main() {
// 创建链表保存数据
struct node* list = createBookList();
// 当文件books.txt已有图书信息时
// 先全部读取所有书本信息
readBookListFromFile(list);
// 显示功能主菜单
showMenu(list);
char a[10];
while (1) {
printf("\n请输出0-6,回车结束!\n");
if (fgets(a, 10, stdin) != NULL) { // 按行读取,0-6字符表示功能
switch (a[0]) {
case '0': // 退出程序
freeBookList(list);
printf("ByeBye,下次再见!\n");
exit(0);
case '1': // 添加图书
addBook(list);
break;
case '2': // 查看图书
queryBook(list);
break;
case '3': // 删除图书
deleteBook(list);
break;
case '4': // 修改图书
updateBook(list);
break;
case '5': // 借书
borrowBook(list);
break;
case '6': // 还书
returnBook(list);
break;
default:
printf("请重新输入正确的功能数字0-6!\n");
}
}
}
return 0;
}
// 创建图书结点
struct node* createBookNode(BOOK *book)
{
struct node* p = (struct node*)calloc(1,sizeof(struct node));
BOOK *b;
if(p != NULL)
{
if(book != NULL)
{
b = &(p->book);
b->id = book->id;
strcpy(b->name, book->name);
b->price = book->price;
strcpy(b->author, book->author);
b->state = book->state;
}
p->next = NULL;
}
return p;
}
// 表尾增加图书结点
struct node* insertBookNode(struct node* head, BOOK *book)
{
if(head != NULL)
{
struct node* node = createBookNode(book);
BOOK *b = &(node->book);
if(node != NULL)
{
struct node* p = head;
// 循环找到链表最后的结点
while(p->next != NULL)
p = p->next;
p->next = node;
return node;
}
}
return NULL;
}
// 创建带头结点的图书空链表
struct node* createBookList()
{
// 创建头结点
return createBookNode(NULL);
}
// 释放图书链表内存空间
void freeBookList(struct node* head)
{
struct node* p = head;
while(p != NULL)
{
head = p->next;
free(p);
p = head;
}
}
// 根据图书ID查找图书结点
struct node* queryBookListById(struct node* head, int id)
{
struct node *p = NULL;
if(head != NULL)
{
p = head->next;
while(p != NULL)
{
if(p->book.id == id)
break;
p = p->next;
}
}
return p;
}
// 根据图书ID删除图书结点
int deleteBookListById(struct node* head, int id)
{
// p保存当前结点,pre保存前一个结点
struct node *p = NULL, *pre = NULL;
// 返回结果0或1
int status = 0;
if(head != NULL)
{
pre = head;
p = head->next;
while(p != NULL)
{
if(p->book.id == id)
{
pre->next = p->next;
free(p);
status = 1;
break;
}
pre = p;
p = p->next;
}
}
return status;
}
// 获取图书链表的长度
int getBookListLength(struct node* head)
{
int n = 0;
struct node *p = NULL;
if(head != NULL)
{
p = head->next;
while(p != NULL)
{
n++;
p = p->next;
}
}
return n;
}
// 打印出链表所有结点保存的图书信息
void printBookListInfo(struct node* head)
{
struct node* p = head->next;
printf("图书编号 书名 价格 作者 借阅状态\n");
BOOK *b;
while(p != NULL)
{
b = &(p->book);
printf("%8d %20s %8.2f %8s %8s\n", b->id, b->name, b->price, \
b->author, (b->state==1 ? "1-未借出":"0-已借出")) ;
p = p->next;
}
}
// 文件保存图书链表所有信息
void saveBookListToFile(struct node* head)
{
if(head != NULL)
{
struct node *p = head->next;
FILE* fp = fopen(BOOK_FILE, "w+");
if(fp != NULL)
{
while(p != NULL)
{
fprintf(fp, "%d %s %f %s %d\n", (p->book).id,\
(p->book).name, (p->book).price, (p->book).author, \
(p->book).state);
p = p->next;
}
fclose(fp);
}else {
error("打开book.txt文件失败,请检查!\n");
}
}
}
// 从文件读取图书信息保存到链表
void readBookListFromFile(struct node* head)
{
FILE* fp = fopen(BOOK_FILE, "a+");
BOOK book;
if (fp != NULL) {
while (fscanf(fp, "%d%s%lf%s%d", &book.id, book.name, \
&book.price, book.author, &book.state) != EOF) {
insertBookNode(head, &book);
}
fclose(fp);
}else {
error("打开book.txt文件失败,请检查!\n");
}
}
// 在屏幕显示各类出错信息,并退出程序
void error(const char* err)
{
printf(err);
exit(-1);
}
void showMenu(struct node *head) {
printf("----------欢迎使用图书管理系统----------\n\n");
printf("当前系统共用图书%d本!\n\n", getBookListLength(head));
printf("系统提供以下功能:\n");
printf("1:添加图书\n");
printf("2:查看图书\n");
printf("3:删除图书\n");
printf("4:修改图书\n");
printf("5:借阅图书\n");
printf("6:归还图书\n");
printf("0:退出系统\n\n");
}
void addBook(struct node *head) {
printf("请您按提示添加图书信息:\n");
printf("依次输入编号 书名 价格 作者信息,以空格分隔:\n");
char a[1024];
BOOK book;
if (fgets(a, 1024, stdin) != NULL && \
sscanf(a, "%d%s%lf%s", &book.id, book.name, \
&book.price, book.author) != EOF) {
// 根据编号查找图书信息,如果编号已存在,则无法增加
if (queryBookListById(head, book.id) != NULL)
printf("该编号对应的图书信息已经存在,无法增加!\n");
else {
book.state = 1;
insertBookNode(head, &book);
saveBookListToFile(head);
printf("添加成功,当前共有%d本图书!\n\n", getBookListLength(head));
}
}
else {
error("输入有误,请重新添加!\n");
}
}
void queryBook(struct node *head) {
printBookListInfo(head);
}
void deleteBook(struct node *head) {
printf("请输入要删除的图书编号:");
char a[1024];
int id;
if (fgets(a, 1024, stdin) != NULL && \
sscanf(a, "%d", &id) != EOF) {
if (deleteBookListById(head, id))
{
printf("该编号%d对应的图书信息删除成功!\n", id);
}else
{
printf("该编号对应的图书信息不存在!\n");
}
}
else {
error("输入有误,请重新输入!\n");
}
}
void updateBook(struct node *head) {
printf("请输入要修改的图书编号:");
char a[1024];
int id = 0;
if (fgets(a, 1024, stdin) != NULL && \
sscanf(a, "%d", &id) != EOF) {
struct node *p = queryBookListById(head, id);
if (p == NULL)
printf("该编号对应的图书信息不存在!\n");
else {
printf("该编号对应的图书信息如下,请按照提示修改:\n");
printf("图书编号 书名 价格 作者 借阅状态\n");
BOOK *book = &(p->book);
printf("%8d %20s %8.2f %8s %8s\n\n",book->id, book->name, \
book->price, book->author, (book->state == 1 ? "未借出" : "已借出"));
printf("依次输入修改后的书名、价格、作者信息,以空格分隔:\n");
if (fgets(a, 1024, stdin) != NULL && sscanf(a, "%s%lf%s",\
book->name, &book->price, book->author) != EOF) {
saveBookListToFile(head);
printf("修改成功,修改后的图书信息如下:\n");
printf("图书编号 书名 价格 作者 借阅状态\n");
printf("%8d %20s %8.2f %8s %8s\n", book->id, book->name, book->price, \
book->author, (book->state == 1 ? "未借出" : "已借出"));
}
else {
error("输入有误,请重新修改!\n");
}
}
}
else {
error("输入有误,请重新输入!\n");
}
}
void borrowBook(struct node *head) {
printf("请输入要借阅的图书编号:");
char a[1024];
int id = 0;
if (fgets(a, 1024, stdin) != NULL && \
sscanf(a, "%d", &id) != EOF) {
struct node *p = queryBookListById(head, id);
if (p == NULL)
printf("该编号对应的图书信息不存在!\n");
else {
printf("该编号对应的图书信息如下,请按照提示修改:\n");
printf("图书编号 书名 价格 作者 借阅状态\n");
BOOK *book = &(p->book);
printf("%8d %20s %8.2f %8s %8s\n\n", book->id, book->name, \
book->price, book->author, (book->state == 1 ? "未借出" : "已借出"));
if (book->state == 0)
printf("该编号对应的图书已借出,请归还后再借阅!\n");
else {
book->state = 0;
saveBookListToFile(head);
printf("该编号对应的图书借阅成功!\n");
}
}
}else {
error("输入有误,请重新输入!\n");
}
}
void returnBook(struct node *head) {
printf("请输入要归还的图书编号:");
char a[1024];
int id = 0;
if (fgets(a, 1024, stdin) != NULL && \
sscanf(a, "%d", &id) != EOF) {
struct node *p = queryBookListById(head, id);
if (p == NULL)
printf("该编号对应的图书信息不存在!\n");
else {
printf("该编号对应的图书信息如下,请按照提示修改:\n");
printf("图书编号 书名 价格 作者 借阅状态\n");
BOOK *book = &(p->book);
printf("%8d %20s %8.2f %8s %8s\n\n", book->id, book->name, \
book->price, book->author, (book->state == 1 ? "未借出" : "已借出"));
if (book->state == 1)
printf("该编号对应的图书未借出,无法归还!\n");
else {
book->state = 1;
saveBookListToFile(head);
printf("该编号对应的图书归还成功!\n");
}
}
}else {
error("输入有误,请重新输入!\n");
}
}
运行结果:
----------欢迎使用图书管理系统----------
当前系统共用图书2本!
系统提供以下功能:
1:添加图书
2:查看图书
3:删除图书
4:修改图书
5:借阅图书
6:归还图书
0:退出系统
请输出0-6,回车结束!
2
图书编号 书名 价格 作者 借阅状态
1 test003 100.10 李四 1-未借出
2 kdk 100.00 dkkd 1-未借出
请输出0-6,回车结束!
其实做为一个学习者,有一个学习的氛围跟一个交流圈子特别重要这里我推荐一个C/C++基础交流583650410,不管你是小白还是转行人士欢迎入驻,大家一起交流成长。
【python设计一个图书管理的简单程序用单链表_轻松学做C语言课程设计(图书管理系统-链表实现...)】
推荐阅读
- python|python-OpenCV-人脸、眼睛,微笑检测
- Python-OpenCv-人脸识别
- python-opencv|7.python-opencv图像张贴
- python-opencv|python-opencv边缘检测
- 力扣算法题-python|力扣算法题总结(python)—二分查找
- python-opencv|5.python-opencv人脸马赛克
- Python 设计模式(单例模式)
- 人工智能|终结 Python 原生字典(这个库要逆天改命了)
- python|终结 Python 原生字典(这个库真的要逆天改命了)
- 程序人生|世界上第一个“半机械人”去世,改造自己只为“逆天改命”