Skip to content

About

C 语言图书管理系统|多文件工程 + 动态数组 + 文件持久化,适合作为第一个稍大的 C 练习项目

Topics

Resources

Stars

7 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

图书管理系统(C 语言)· 适合作为你的第一个"大一点"的 C 项目

一个用纯 C 写的控制台图书管理系统:管理员管理用户和图书,读者登录后借书、还书、查看自己的借阅记录。 没有第三方库,只有标准库,git clone 下来就能编译运行。

项目规模:28 个源文件(inc/ + src/)/ 2000+ 行代码——比课本上"单文件 200 行"的作业大得多, 又比真实项目小得多,正好卡在"能看懂、但一个人写会乱"的区间,是练多文件工程的最佳尺寸。


为什么适合拿来练手

你会在这个项目里遇到 对应到哪里看
.h 和 .c 为什么分开、怎么分 inc/ 与 src/ 一一对应,接口放头文件
一个字段要贯穿五个环节 见 练习任务 第 2 题
动态数组(顺序表)与扩容 src/user_list.c 的 realloc
数据怎么持久化到文件 src/*_file.c,逗号分隔的纯文本
界面 / 数据 / 存储怎么分层 阅读指南 的分层图
边界情况怎么处理 read_int / input_ended,以及下面"踩坑记录"
Git 日常操作 如何用 Git 学习

快速开始

方式一:VS Code(推荐,配置已经写好)

  1. VS Code → 文件 → 打开文件夹 → 选择本项目目录
  2. 按 F5:编译 + 启动调试(可以打断点单步走)
  3. 按 Ctrl+F5:编译 + 直接运行
  4. 按 Cmd+Shift+B / Ctrl+Shift+B:只编译

.vscode/tasks.json 里默认用的是 /usr/bin/clang(macOS)。 Windows 用户把其中的 command 改成 gcc、把 -o 后面的文件名加个 .exe 即可。

方式二:命令行

# macOS / Linux
cc -g -Wall -Wextra -I inc src/*.c -o bin/library && ./bin/library

# Windows(MinGW / Git Bash)
gcc -g -Wall -Wextra -I inc src/*.c -o bin/library.exe && ./bin/library.exe

方式三:用 Makefile

make        # 编译,生成 bin/library
make run    # 编译并运行
make clean  # 清理编译产物

⚠️ 必须在项目根目录运行程序:数据文件用的是相对路径 data/user.data, 换到别的目录运行会新建一份空数据。


演示账号

身份 账号 密码
管理员 admin admin123(在 src/admin.c 顶部修改)
读者 zhangsan 111111
读者 lisi 222222
读者 wangwu 333333

功能一览

功能菜单:1.管理员登录 2.用户登录 0.退出系统

管理员功能:1.用户管理 2.图书管理 3.借阅记录查询 0.退出管理员登录
  用户管理:1.添加用户 2.删除用户 3.查询用户列表 4.修改用户 5.按ID查询 6.按姓名查询 0.退出
  图书管理:1.添加图书 2.删除图书 3.查询图书列表 4.修改图书 5.按ID查询 6.按书名查询 0.退出
  借阅记录:1.查看全部借阅记录 2.按用户查询 3.按图书查询 4.查看未归还记录 0.退出

用户功能:1.查询图书 2.借书 3.还书 4.我的借阅记录 0.退出登录

借书会扣库存并生成借阅记录,还书会加回库存并把记录标记为已归还——内存和文件同时更新。


项目结构

.
├─ .vscode/            # VS Code 编译与调试配置(不用改)
├─ inc/                # 头文件:模块对外提供的接口
├─ src/                # 源文件:具体实现
├─ data/               # 数据文件(纯文本,逗号分隔)
├─ docs/               # 阅读指南 / 练习任务 / Git 教程
├─ Makefile
└─ README.md

源码按职责分三层,看文件名就能认出来:

文件 是什么
main.c / admin*.c / user.c 界面层:打印菜单、读键盘
*_list.c 数据层:内存里的动态数组
*_file.c 持久化层:内存 ↔ 文件
view.c / util.c / common.h 表格打印 / 工具函数 / 全局常量

详细的调用关系见 阅读指南。


建议的学习路线

  1. 先跑起来:编译、运行,把菜单每个功能都点一遍,建立直观印象
  2. 再读代码:跟着 阅读指南 走三条主线(启动 / 借书 / 添加图书), 在 src/user.c 的 user_borrow_book() 打个断点,用 F10/F11 单步走一遍
  3. 然后改代码:从 练习任务 的一档开始,每做完一题提交一次 Git
  4. 最后重构:做三档任务(抽业务层、换链表实现),体会"接口不变、实现全换"

数据文件

三个纯文本文件,逗号分隔,可以直接用记事本打开看:

data/user.data    用户ID,用户名,密码,手机号,邮箱,姓名
data/book.data    图书ID,书名,作者,出版社,库存
data/borrow.data  用户ID,图书ID,借出日期,归还日期,状态(0=借出未还,1=已归还)

程序启动时把文件读进内存,之后每次增删改都会立刻写回文件。 不要在程序运行时手工编辑这些文件,否则内存和文件会不一致; 想手动改,先退出程序,改完再启动(或者干脆删掉文件,让程序从空数据开始)。


踩坑记录(真实的 bug,值得一读)

开发过程中踩过一个很典型的坑,写在这里当教材:

用 ./library > 输出.txt 的方式运行程序,输入被重定向读完(EOF)后, 某个读取函数陷入了死循环,每秒往文件里写几百 MB,十几分钟把整块硬盘写满了。

根因是:输入结束后 read_str() 一直返回空串,而"输入不能为空"的校验循环没退出。 修法是引入 input_ended()(见 src/util.c)并在每个菜单循环里检查它。

这件事的教训,比代码本身更值钱:

  1. 每个 while (1) 都要有明确的退出条件,包括"输入没了"这种情况
  2. 输入中断时不要写数据——否则会把空值当用户输入存进文件
  3. 别用 > 文件 跑交互式程序;要跑就用 ulimit -f 限一下文件大小,或者用 timeout

文档


许可证

MIT——随便用,拿来交作业、改成自己的项目都行。

About

C 语言图书管理系统|多文件工程 + 动态数组 + 文件持久化,适合作为第一个稍大的 C 练习项目

Topics

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages