fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. typedef enum {
  6. STATUS_RETURNED = 0, /* 已归还/在馆 */
  7. STATUS_BORROWED = 1 /* 已借出 */
  8. } BookStatus;
  9.  
  10. typedef struct Book {
  11. char title[50];
  12. char publisher[50];
  13. char borrow_date[20];
  14. char return_date[20];
  15. BookStatus status;
  16. struct Book *next;
  17. } Book;
  18.  
  19. Book *head = NULL; /* 链表头指针 */
  20.  
  21. /* ---------- 输入辅助:读一整行,去掉换行 ---------- */
  22. void read_line(char *buf, size_t size) {
  23. if (fgets(buf, (int)size, stdin) == NULL) {
  24. buf[0] = '\0';
  25. return;
  26. }
  27. if (strchr(buf, '\n') == NULL) { /* 输入超长,清掉残留 */
  28. int c;
  29. while ((c = getchar()) != '\n' && c != EOF) { }
  30. } else {
  31. buf[strcspn(buf, "\n")] = '\0';
  32. }
  33. }
  34.  
  35. const char *status_text(BookStatus s) {
  36. return s == STATUS_BORROWED ? "借出" : "归还";
  37. }
  38.  
  39. /* ---------- 添加图书(尾插,保持录入顺序) ---------- */
  40. void add_book(void) {
  41. Book *b = (Book *)malloc(sizeof(Book));
  42. if (b == NULL) { printf("内存分配失败!\n"); return; }
  43.  
  44. printf("书名: ");
  45. read_line(b->title, sizeof(b->title));
  46. if (b->title[0] == '\0') { printf("书名不能为空!\n"); free(b); return; }
  47.  
  48. printf("出版社: ");
  49. read_line(b->publisher, sizeof(b->publisher));
  50. printf("借出时间(如 2024-05-01,可为 -): ");
  51. read_line(b->borrow_date, sizeof(b->borrow_date));
  52. printf("归还时间(如 2024-06-01,可为 -): ");
  53. read_line(b->return_date, sizeof(b->return_date));
  54.  
  55. char line[16];
  56. printf("状态(0=归还/在馆, 1=借出): ");
  57. read_line(line, sizeof(line));
  58. b->status = (atoi(line) == 1) ? STATUS_BORROWED : STATUS_RETURNED;
  59.  
  60. b->next = NULL;
  61. if (head == NULL) {
  62. head = b;
  63. } else {
  64. Book *p = head;
  65. while (p->next != NULL) p = p->next;
  66. p->next = b;
  67. }
  68. printf("添加成功!\n");
  69. }
  70.  
  71. /* ---------- 显示辅助 ---------- */
  72. void print_header(void) {
  73. printf("%-20s %-20s %-14s %-14s %-6s\n",
  74. "书名", "出版社", "借出时间", "归还时间", "状态");
  75. printf("--------------------------------------------------------------------------------\n");
  76. }
  77.  
  78. void print_book(Book *b) {
  79. printf("%-20s %-20s %-14s %-14s %-6s\n",
  80. b->title, b->publisher,
  81. b->borrow_date, b->return_date,
  82. status_text(b->status));
  83. }
  84.  
  85. /* ---------- 查找:按书名(模糊匹配) ---------- */
  86. void search_by_title(void) {
  87. char key[50];
  88. printf("输入书名关键字: ");
  89. read_line(key, sizeof(key));
  90.  
  91. int count = 0;
  92. print_header();
  93. for (Book *p = head; p != NULL; p = p->next) {
  94. if (strstr(p->title, key) != NULL) {
  95. print_book(p);
  96. count++;
  97. }
  98. }
  99. printf("共找到 %d 本图书\n", count);
  100. }
  101.  
  102. /* ---------- 查找:按出版社(模糊匹配) ---------- */
  103. void search_by_publisher(void) {
  104. char key[50];
  105. printf("输入出版社关键字: ");
  106. read_line(key, sizeof(key));
  107.  
  108. int count = 0;
  109. print_header();
  110. for (Book *p = head; p != NULL; p = p->next) {
  111. if (strstr(p->publisher, key) != NULL) {
  112. print_book(p);
  113. count++;
  114. }
  115. }
  116. printf("共找到 %d 本图书\n", count);
  117. }
  118.  
  119. /* ---------- 删除的匹配函数 ---------- */
  120. int match_title(Book *b, const char *key) {
  121. return strcmp(b->title, key) == 0;
  122. }
  123.  
  124. int match_publisher(Book *b, const char *key) {
  125. return strcmp(b->publisher, key) == 0;
  126. }
  127.  
  128. /* 通用删除:删除所有匹配节点,返回删除数量 */
  129. int delete_books(int (*match)(Book *, const char *), const char *key) {
  130. Book *prev = NULL;
  131. Book *cur = head;
  132. int count = 0;
  133.  
  134. while (cur != NULL) {
  135. if (match(cur, key)) {
  136. Book *del = cur;
  137. if (prev == NULL) head = cur->next; /* 删除头节点 */
  138. else prev->next = cur->next; /* 删除中间/尾节点 */
  139. cur = cur->next;
  140. free(del);
  141. count++;
  142. } else {
  143. prev = cur;
  144. cur = cur->next;
  145. }
  146. }
  147. return count;
  148. }
  149.  
  150. void delete_by_title(void) {
  151. char key[50];
  152. printf("输入要删除的书名(完整): ");
  153. read_line(key, sizeof(key));
  154. int n = delete_books(match_title, key);
  155. if (n > 0) printf("已删除 %d 本图书\n", n);
  156. else printf("未找到该书\n");
  157. }
  158.  
  159. void delete_by_publisher(void) {
  160. char key[50];
  161. printf("输入要删除的出版社(完整): ");
  162. read_line(key, sizeof(key));
  163. int n = delete_books(match_publisher, key);
  164. if (n > 0) printf("已删除 %d 本图书\n", n);
  165. else printf("未找到该出版社的图书\n");
  166. }
  167.  
  168. /* ---------- 借出 / 归还登记(修改状态和时间) ---------- */
  169. void change_status(void) {
  170. char title[50];
  171. printf("输入书名: ");
  172. read_line(title, sizeof(title));
  173.  
  174. Book *p = head;
  175. while (p != NULL && strcmp(p->title, title) != 0) p = p->next;
  176. if (p == NULL) { printf("未找到该书\n"); return; }
  177.  
  178. char line[16];
  179. printf("1=借出 0=归还: ");
  180. read_line(line, sizeof(line));
  181. if (atoi(line) == 1) {
  182. p->status = STATUS_BORROWED;
  183. printf("借出时间: ");
  184. read_line(p->borrow_date, sizeof(p->borrow_date));
  185. } else {
  186. p->status = STATUS_RETURNED;
  187. printf("归还时间: ");
  188. read_line(p->return_date, sizeof(p->return_date));
  189. }
  190. printf("状态已更新\n");
  191. }
  192.  
  193. /* ---------- 显示全部 ---------- */
  194. void list_books(void) {
  195. if (head == NULL) { printf("暂无图书\n"); return; }
  196. print_header();
  197. for (Book *p = head; p != NULL; p = p->next) print_book(p);
  198. }
  199.  
  200. /* ---------- 释放整条链表 ---------- */
  201. void free_all(void) {
  202. Book *p = head;
  203. while (p != NULL) {
  204. Book *next = p->next;
  205. free(p);
  206. p = next;
  207. }
  208. head = NULL;
  209. }
  210.  
  211. /* ---------- 主函数 ---------- */
  212. int main(void) {
  213. char line[32];
  214. while (1) {
  215. printf("\n========== 图书管理系统(链表版) ==========\n");
  216. printf("1. 添加图书\n");
  217. printf("2. 按书名查找\n");
  218. printf("3. 按出版社查找\n");
  219. printf("4. 按书名删除\n");
  220. printf("5. 按出版社删除\n");
  221. printf("6. 显示全部图书\n");
  222. printf("7. 借出/归还登记\n");
  223. printf("0. 退出\n");
  224. printf("请选择: ");
  225.  
  226. read_line(line, sizeof(line));
  227. int choice = atoi(line);
  228.  
  229. switch (choice) {
  230. case 1: add_book(); break;
  231. case 2: search_by_title(); break;
  232. case 3: search_by_publisher(); break;
  233. case 4: delete_by_title(); break;
  234. case 5: delete_by_publisher(); break;
  235. case 6: list_books(); break;
  236. case 7: change_status(); break;
  237. case 0:
  238. free_all();
  239. printf("再见!\n");
  240. return 0;
  241. default:
  242. printf("无效选项,请重新输入\n");
  243. }
  244. }
  245. return 0;
  246. }
Success #stdin #stdout 0s 5340KB
stdin
Standard input is empty
stdout
========== 图书管理系统(链表版) ==========
1. 添加图书
2. 按书名查找
3. 按出版社查找
4. 按书名删除
5. 按出版社删除
6. 显示全部图书
7. 借出/归还登记
0. 退出
请选择: 再见!