C语言中文社区
学习路线 | AI编程 | 代码实例 | 实战源码 | 开发工具 | 视频教程 | 面试题 | 电子书 | 专注于C语言编程技术分享
186篇原创内容
公众号
文末附完整源代码
本图书管理系统使用C语言实现,采用链表数据结构存储图书信息,并提供基本的增删改查功能。系统将数据持久化存储到二进制文件中,确保程序关闭后数据不会丢失。
Book结构体:
typedef struct Book {
int id; // 图书ID
char title[]; // 书名
char author[]; // 作者
char publisher[]; // 出版社
float price; // 价格
struct Book *next; // 指向下一个节点的指针
} Book;
id
: 唯一标识每本图书的整数IDtitle
: 存储书名的字符数组author
: 存储作者信息的字符数组publisher
: 存储出版社信息的字符数组price
: 存储图书价格的浮点数next
: 指向链表中下一个节点的指针books.dat
)存储数据CLion:
D:\CODING\cyyzwsq\BooksMS\cmake-build-debug\BooksMS.exe
未找到数据文件,将创建新文件。
图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):1
请输入图书ID:1001
请输入书名:C语言
请输入作者:张三
请输入出版社:ABC
请输入价格:55
图书添加成功!
数据已保存到文件!
图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):2
ID 书名 作者 出版社 价格
------------------------------------------------------------
1001 C语言 张三 ABC 55.00
图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):1
请输入图书ID:1002
请输入书名:C++
请输入作者:李四
请输入出版社:BBB
请输入价格:66
图书添加成功!
数据已保存到文件!
图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):2
ID 书名 作者 出版社 价格
------------------------------------------------------------
1002 C++ 李四 BBB 66.00
1001 C语言 张三 ABC 55.00
图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):3
请选择查询方式:
1. 按ID查询
2. 按书名查询
3. 按作者查询
请输入选择(1-3):1
请输入要查询的图书ID:1002
查询结果:
ID: 1002
书名: C++
作者: 李四
出版社: BBB
价格: 66.00
图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):5
请输入要修改的图书ID:1002
当前图书信息:
ID: 1002
书名: C++
作者: 李四
出版社: BBB
价格: 66.00
请输入新的书名(留空则不修改):
请输入新的作者(留空则不修改):
请输入新的出版社(留空则不修改):CCC
请输入新的价格(留空则不修改):77
图书信息修改成功!
数据已保存到文件!
图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):2
ID 书名 作者 出版社 价格
------------------------------------------------------------
1002 C++ 李四 CCC 77.00
1001 C语言 张三 ABC 55.00
图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// 定义图书结构体
typedefstruct Book {
int id; // 图书ID
char title[]; // 书名
char author[]; // 作者
char publisher[]; // 出版社
float price; // 价格
struct Book *next;// 指向下一个节点的指针
} Book;
// 全局变量,指向链表头
Book *head = NULL;
// 函数声明
void addBook();
void displayBooks();
void searchBook();
void deleteBook();
void modifyBook();
void saveToFile();
void loadFromFile();
void menu();
void toLowerCase(char *str);
int main() {
loadFromFile(); // 程序启动时加载数据
menu(); // 显示主菜单
return;
}
// 添加图书
void addBook() {
Book *newBook = (Book *)malloc(sizeof(Book));
if (newBook == NULL) {
printf("内存分配失败!\n");
return;
}
printf("请输入图书ID: ");
scanf("%d", &newBook->id);
getchar(); // 清除输入缓冲区中的换行符
printf("请输入书名: ");
fgets(newBook->title, sizeof(newBook->title), stdin);
newBook->title[strcspn(newBook->title, "\n")] = '\0'; // 去除换行符
printf("请输入作者: ");
fgets(newBook->author, sizeof(newBook->author), stdin);
newBook->author[strcspn(newBook->author, "\n")] = '\0';
printf("请输入出版社: ");
fgets(newBook->publisher, sizeof(newBook->publisher), stdin);
newBook->publisher[strcspn(newBook->publisher, "\n")] = '\0';
printf("请输入价格: ");
scanf("%f", &newBook->price);
// 将新书添加到链表头部
newBook->next = head;
head = newBook;
printf("图书添加成功!\n");
saveToFile(); // 添加后立即保存到文件
}
// 显示所有图书
void displayBooks() {
if (head == NULL) {
printf("当前没有图书记录!\n");
return;
}
Book *current = head;
printf("\n%-10s %-30s %-20s %-20s %-10s\n",
"ID", "书名", "作者", "出版社", "价格");
printf("------------------------------------------------------------\n");
while (current != NULL) {
printf("%-10d %-30s %-20s %-20s %-10.2f\n",
current->id, current->title, current->author,
current->publisher, current->price);
current = current->next;
}
}
// 查询图书
void searchBook() {
if (head == NULL) {
printf("当前没有图书记录!\n");
return;
}
int choice;
printf("请选择查询方式:\n");
printf("1. 按ID查询\n");
printf("2. 按书名查询\n");
printf("3. 按作者查询\n");
printf("请输入选择(1-3): ");
scanf("%d", &choice);
getchar(); // 清除输入缓冲区
Book *current = head;
int found = ;
switch (choice) {
case: {
int searchId;
printf("请输入要查询的图书ID: ");
scanf("%d", &searchId);
while (current != NULL) {
if (current->id == searchId) {
printf("\n查询结果:\n");
printf("ID: %d\n书名: %s\n作者: %s\n出版社: %s\n价格: %.2f\n",
current->id, current->title, current->author,
current->publisher, current->price);
found = ;
break;
}
current = current->next;
}
break;
}
case: {
char searchTitle[];
printf("请输入要查询的书名: ");
fgets(searchTitle, sizeof(searchTitle), stdin);
searchTitle[strcspn(searchTitle, "\n")] = '\0';
// 转换为小写以便不区分大小写比较
char lowerTitle[];
strcpy(lowerTitle, searchTitle);
toLowerCase(lowerTitle);
while (current != NULL) {
char lowerCurrent[];
strcpy(lowerCurrent, current->title);
toLowerCase(lowerCurrent);
if (strstr(lowerCurrent, lowerTitle) != NULL) {
printf("\n查询结果:\n");
printf("ID: %d\n书名: %s\n作者: %s\n出版社: %s\n价格: %.2f\n",
current->id, current->title, current->author,
current->publisher, current->price);
found = ;
}
current = current->next;
}
break;
}
case: {
char searchAuthor[];
printf("请输入要查询的作者: ");
fgets(searchAuthor, sizeof(searchAuthor), stdin);
searchAuthor[strcspn(searchAuthor, "\n")] = '\0';
// 转换为小写以便不区分大小写比较
char lowerAuthor[];
strcpy(lowerAuthor, searchAuthor);
toLowerCase(lowerAuthor);
while (current != NULL) {
char lowerCurrent[];
strcpy(lowerCurrent, current->author);
toLowerCase(lowerCurrent);
if (strstr(lowerCurrent, lowerAuthor) != NULL) {
printf("\n查询结果:\n");
printf("ID: %d\n书名: %s\n作者: %s\n出版社: %s\n价格: %.2f\n",
current->id, current->title, current->author,
current->publisher, current->price);
found = ;
}
current = current->next;
}
break;
}
default:
printf("无效的选择!\n");
return;
}
if (!found) {
printf("未找到匹配的图书!\n");
}
}
// 删除图书
void deleteBook() {
if (head == NULL) {
printf("当前没有图书记录!\n");
return;
}
int deleteId;
printf("请输入要删除的图书ID: ");
scanf("%d", &deleteId);
Book *current = head;
Book *prev = NULL;
int found = ;
while (current != NULL) {
if (current->id == deleteId) {
found = ;
if (prev == NULL) {
// 删除的是头节点
head = current->next;
} else {
prev->next = current->next;
}
free(current);
printf("图书删除成功!\n");
saveToFile(); // 删除后立即保存到文件
break;
}
prev = current;
current = current->next;
}
if (!found) {
printf("未找到ID为%d的图书!\n", deleteId);
}
}
// 修改图书信息
void modifyBook() {
if (head == NULL) {
printf("当前没有图书记录!\n");
return;
}
int modifyId;
printf("请输入要修改的图书ID: ");
scanf("%d", &modifyId);
getchar(); // 清除输入缓冲区
Book *current = head;
int found = ;
while (current != NULL) {
if (current->id == modifyId) {
found = ;
printf("当前图书信息:\n");
printf("ID: %d\n书名: %s\n作者: %s\n出版社: %s\n价格: %.2f\n",
current->id, current->title, current->author,
current->publisher, current->price);
printf("请输入新的书名(留空则不修改): ");
char newTitle[];
fgets(newTitle, sizeof(newTitle), stdin);
if (newTitle[] != '\n') {
newTitle[strcspn(newTitle, "\n")] = '\0';
strcpy(current->title, newTitle);
}
printf("请输入新的作者(留空则不修改): ");
char newAuthor[];
fgets(newAuthor, sizeof(newAuthor), stdin);
if (newAuthor[] != '\n') {
newAuthor[strcspn(newAuthor, "\n")] = '\0';
strcpy(current->author, newAuthor);
}
printf("请输入新的出版社(留空则不修改): ");
char newPublisher[];
fgets(newPublisher, sizeof(newPublisher), stdin);
if (newPublisher[] != '\n') {
newPublisher[strcspn(newPublisher, "\n")] = '\0';
strcpy(current->publisher, newPublisher);
}
printf("请输入新的价格(留空则不修改): ");
char priceStr[];
fgets(priceStr, sizeof(priceStr), stdin);
if (priceStr[] != '\n') {
current->price = atof(priceStr);
}
printf("图书信息修改成功!\n");
saveToFile(); // 修改后立即保存到文件
break;
}
current = current->next;
}
if (!found) {
printf("未找到ID为%d的图书!\n", modifyId);
}
}
// 将链表数据保存到文件
void saveToFile() {
FILE *file = fopen("books.dat", "wb");
if (file == NULL) {
printf("无法打开文件进行保存!\n");
return;
}
Book *current = head;
while (current != NULL) {
fwrite(current, sizeof(Book), , file);
current = current->next;
}
fclose(file);
printf("数据已保存到文件!\n");
}
// 从文件加载数据到链表
void loadFromFile() {
FILE *file = fopen("books.dat", "rb");
if (file == NULL) {
printf("未找到数据文件,将创建新文件。\n");
return;
}
// 清空现有链表
Book *current = head;
while (current != NULL) {
Book *temp = current;
current = current->next;
free(temp);
}
head = NULL;
// 从文件读取数据
Book book;
while (fread(&book, sizeof(Book), , file) == ) {
Book *newBook = (Book *)malloc(sizeof(Book));
if (newBook == NULL) {
printf("内存分配失败!\n");
break;
}
*newBook = book;
newBook->next = head;
head = newBook;
}
fclose(file);
printf("数据已从文件加载!\n");
}
// 将字符串转换为小写
void toLowerCase(char *str) {
for (int i = ; str[i]; i++) {
str[i] = tolower(str[i]);
}
}
// 显示主菜单
void menu() {
int choice;
do {
printf("\n图书管理系统\n");
printf("1. 添加图书\n");
printf("2. 显示所有图书\n");
printf("3. 查询图书\n");
printf("4. 删除图书\n");
printf("5. 修改图书信息\n");
printf("6. 保存数据到文件\n");
printf("7. 从文件加载数据\n");
printf("0. 退出\n");
printf("请输入您的选择(0-7): ");
scanf("%d", &choice);
getchar(); // 清除输入缓冲区
switch (choice) {
case: addBook(); break;
case: displayBooks(); break;
case: searchBook(); break;
case: deleteBook(); break;
case: modifyBook(); break;
case: saveToFile(); break;
case: loadFromFile(); break;
case:
saveToFile(); // 退出前保存数据
printf("感谢使用图书管理系统,再见!\n");
break;
default:
printf("无效的选择,请重新输入!\n");
}
} while (choice != );
}