C语言图书库管理系统:容量限制与do-while循环异常修复需求
图书库管理程序问题修复方案
针对你遇到的三个问题,以下是具体的代码调整和修复逻辑:
问题1:库满时阻止添加图书并返回主菜单
主菜单逻辑中,用户选添加图书(选项1)且库已达容量上限时,需显示提示后回到菜单,修改主函数的判断代码:
// 原代码 if (decision == 1 && size == MAX_LIBRARY_SIZE){ /*printf("List is full\n");*/ continue; } // 修改后 if (decision == 1 && size == MAX_LIBRARY_SIZE){ printf("List is full\n"); continue; }
问题2:库满时替换"Invalid ISBN"提示并返回主菜单
addBook函数的ISBN循环里,原逻辑仅break跳出循环,仍会执行后续日期、分类输入,需改为直接退出函数:
// 修改addBook中的ISBN循环部分 do { if (*size == MAX_LIBRARY_SIZE){ printf("List is full\n"); return; // 直接退出addBook,返回主菜单 } printf("ISBN: >"); scanf(" %11s", isbnBuf); while ((x = getchar()) != '\n' && x != EOF); size_t len = strlen(isbnBuf); valid = 1; size_t i; for (i = 0; i < len; i++){ if (isbnBuf[i] < '0' || isbnBuf[i] > '9'){ valid = 0; break; } } if (len > 11 || !valid){ printf("Invalid ISBN. "); } else { strcpy((*library)[*size].isbn, isbnBuf); break; } } while(1);
同时保留addBook开头的库满检测,作为第一道拦截:
void addBook(book_t **library, int *size){ if (*size == MAX_LIBRARY_SIZE){ printf("List is full\n"); return; } // ... 其余代码 }
问题3:移除do-while循环导致功能失效的修复
你添加的判断语句位置错误,且仅break无法终止整个添加流程。正确逻辑是:
- 保留
addBook开头的库满检测(拦截大部分情况) - 保留主菜单的库满检测(二次拦截)
- ISBN循环中的库满检测改为return(处理极端边界)
ISBN的do-while循环是验证格式的必要逻辑,无需移除。
额外小问题修复
- 日期输入的指针访问错误:将
&library[*size]->publication_date.month改为&(*library)[*size].publication_date.month,避免内存访问异常。 FileToSerial函数需传递size指针才能更新库大小:
// 修改函数原型 void FileToSerial(book_t *library, int *size, const char *filename); // 修改函数内的size赋值 if (i >= MAX_LIBRARY_SIZE){ *size = MAX_LIBRARY_SIZE; break; } else { *size = i; }
完整修复后代码
#include <stdlib.h> #include <stdio.h> #include <string.h> #define MAX_LIBRARY_SIZE 2 #define MAX_TITLE_SIZE 50 #define MAX_AUTHOR_SIZE 50 typedef struct { unsigned int month; unsigned int year; } date; typedef struct { char title[MAX_TITLE_SIZE]; char author[MAX_AUTHOR_SIZE]; char isbn[20]; date publication_date; char genre[50]; } book_t; void printMenu(void); void addBook(book_t **library, int *size); void deleteBook(int *size); void libraryToFile(book_t *library, int size, const char *filename); void displayLibrary(book_t *library, int *size); void FileToSerial(book_t *library, int *size, const char *filename); int main(void){ book_t *library = NULL; const char fileName[] = "database"; int size = 0; int decision; do { printMenu(); printf("Enter your choice>\n"); if (scanf("%i", &decision) != 1 || decision < 1 || decision > 6){ printf("Invalid choice.\n"); while (getchar() != '\n'); continue; } if (decision == 1 && size == MAX_LIBRARY_SIZE){ printf("List is full\n"); continue; } switch(decision){ case 1: addBook(&library, &size); break; case 2: if (size == 0){ printf("List is empty\n"); } else { deleteBook(&size); } break; case 3: if (size == 0){ printf("List is empty\n"); } else { displayLibrary(library, &size); } break; case 4: if (size == 0){ printf("List is empty\n"); } else { libraryToFile(library, size, fileName); } break; case 5: FileToSerial(library, &size, fileName); break; case 6: free(library); return 1; } } while (1); return 0; } void printMenu(void){ printf("\nLibrary Management System \n" "1. Add book\n" "2. Delete last book\n" "3. Display book list\n" "4. Save the book list to the database\n" "5. Read the book list from the database\n" "6. Exit the program\n"); } void addBook(book_t **library, int *size){ if (*size == MAX_LIBRARY_SIZE){ printf("List is full\n"); return; } if (*library == NULL){ *library = (book_t*)malloc(MAX_LIBRARY_SIZE * sizeof(book_t)); if (*library == NULL){ printf("Memory allocation failed\n"); return; } } int x; while ((x = getchar()) != '\n' && x != EOF); printf("Title: >"); scanf(" %15s", (*library)[*size].title); while ((x = getchar()) != '\n' && x != EOF); printf("Author: >"); scanf(" %14s", (*library)[*size].author); while ((x = getchar()) != '\n' && x != EOF); char isbnBuf[12]; int valid = 0; do { if (*size == MAX_LIBRARY_SIZE){ printf("List is full\n"); return; } printf("ISBN: >"); scanf(" %11s", isbnBuf); while ((x = getchar()) != '\n' && x != EOF); size_t len = strlen(isbnBuf); valid = 1; size_t i; for (i = 0; i < len; i++){ if (isbnBuf[i] < '0' || isbnBuf[i] > '9'){ valid = 0; break; } } if (len > 11 || !valid){ printf("Invalid ISBN. "); } else { strcpy((*library)[*size].isbn, isbnBuf); break; } } while(1); printf("Publication_date(month): >"); scanf("%2u", &(*library)[*size].publication_date.month); while ((*library)[*size].publication_date.month < 1 || (*library)[*size].publication_date.month > 12){ printf("Invalid month. "); printf("Publication_date(month): >"); scanf("%u", &(*library)[*size].publication_date.month); int i; while ((i = getchar()) != '\n'); } printf("Publication_date(year): >"); scanf("%4u", &(*library)[*size].publication_date.year); while ((*library)[*size].publication_date.year < 1950 || (*library)[*size].publication_date.year > 2024) { printf("Invalid year. "); printf("Publication_date(year): >"); scanf("%u", &(*library)[*size].publication_date.year); int i; while ((i = getchar()) != '\n'); } printf("Genre: >"); scanf(" %10s", (*library)[*size].genre); while ((x = getchar()) != '\n' && x != EOF); (*size)++; printf("\n"); } void deleteBook(int *size){ if(*size == 0){ printf("List is empty\n"); return; } (*size)--; } void libraryToFile(book_t *library, int size, const char *filename){ if (library == NULL){ printf("Library is empty\n"); return; } FILE *file = fopen(filename, "w"); if (file == NULL) { printf("Error opening file!\n"); return; } int i; for (i = 0; i < size; i++){ book_t book = library[i]; fprintf(file, "%s\t%s\t%s\t%d%d\t%s\n", book.title, book.author, book.isbn, book.publication_date.month, book.publication_date.year, book.genre); } fclose(file); } void displayLibrary(book_t *library, int *size){ if(library == NULL){ printf("Library is empty\n"); return; } if(*size == 0){ printf("List is empty\n"); } else { printf("Title Author ISBN Pub. Date Genre\n" "---------- ---------- ---------- --------- --------"); printf("\n"); int i; for (i = 0; i < *size; i++){ book_t book = library[i]; printf("%-10.10s %-10.10s %-10s %02u-%4u %s", book.title, book.author, book.isbn, book.publication_date.month, book.publication_date.year, book.genre); printf("\n"); } } } void FileToSerial(book_t *library, int *size, const char *filename){ if (library == NULL){ printf("Read error\n"); return; } FILE *file = fopen(filename, "r"); if (file != NULL){ book_t book; int i = 0; while (fscanf(file, "%15s %15s %11s %2u%4u %10s", book.title, book.author, book.isbn, &book.publication_date.month, &book.publication_date.year, book.genre) != EOF){ library[i] = book; i++; if (i >= MAX_LIBRARY_SIZE){ *size = MAX_LIBRARY_SIZE; break; } else { *size = i; } } fclose(file); } else { printf("Read error\n"); } }
内容的提问来源于stack exchange,提问作者9_daytona
相关产品推荐
相关产品推荐

