You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言图书管理系统计数异常、作者搜索失败问题求解

问题修复方案

1 add函数中p始终为0的修复

问题原因

  • 你以a追加模式打开文件,此时文件指针默认指向文件末尾,调用numofbooks统计数量时从末尾开始读,自然读不到任何:字符,返回值恒为0
  • numofbooks函数执行完后文件指针会停在EOF位置,后续如果要操作文件需要重置指针位置

修复代码

修改add函数的文件打开和统计逻辑:

void add() {
    int ans = 1;
    static int p;
    unsigned price, bpages, numavail;
    FILE *ptr = NULL;

    system("cls");
    // 先以只读模式打开统计数量
    ptr = fopen("books info.txt", "r");
    if (ptr == NULL) {
        // 文件不存在则先创建空文件
        ptr = fopen("books info.txt", "w");
        if (ptr == NULL) {
            printf("Couldn't open the file....");
            exit(1);
        }
        fclose(ptr);
        ptr = fopen("books info.txt", "r");
    }
    p = numofbooks(ptr);
    fclose(ptr);
    printf("%d", p); // 此时可以正常输出已有图书数量
    // 统计完成后再以追加模式打开写入新数据
    ptr = fopen("books info.txt", "a");
    if (ptr == NULL) {
        printf("Couldn't open the file....");
        exit(1);
    }

    // 原有新增图书的循环逻辑保留即可
    while (ans == 1) {
        printf("\nEnter The name of the book: ");
        fflush(stdin);
        gets(info[p].bname);
        fprintf(ptr, "Book name: %s\n", info[p].bname);
        fflush(stdin);
        printf("Enter The author of this book: ");
        gets(info[p].bauthor);
        fprintf(ptr, "Book author: %s\n", info[p].bauthor);
        fflush(stdin);
        printf("Enter The number of pages of this book: ");
        scanf("%u", &info[p].bpages);
        fprintf(ptr, "Number of pages: %u\n", info[p].bpages);
        fflush(stdin);
        printf("What is the price of the book (in EGP)? ");
        scanf("%u", &info[p].price);
        fprintf(ptr, "Price (in EGP): %u\n", info[p].price);
        printf("Number of books available: ");
        scanf("%u", &info[p].numavail);
        fprintf(ptr, "Number of books available: %u", info[p].numavail);
        fprintf(ptr, "\n---------------------------------------------------------\n");
        printf("\nBook information saved successfully....\n");
        p++; // 新增完成后p自增,方便连续新增多本图书
        fflush(stdin);
        printf("\nEnter (1) to add another book, (0) to exit or (2) for main menu. ");
        scanf("%d", &ans);
        if (ans == 2) {
            fclose(ptr);
            system("cls");
            return; // 不要直接调用main(),会导致栈溢出,用return返回主菜单即可
        }
    }
    fclose(ptr);
}

2 searchauthor函数始终输出Not found的修复

问题原因

  • 文件名写错:代码中打开的是books info,正确文件名是books info.txt,缺少后缀导致文件打开失败,统计到的图书数量为0,循环不会执行
  • 没有把文件中的图书数据加载到全局info结构体数组中,搜索时是在空数组中做比对,自然找不到匹配项
  • gets函数已被C标准废弃,容易出现缓冲区溢出问题,同时输入长度和结构体定义的长度不匹配也可能导致比对失败

修复步骤

  1. 先实现数据加载函数,把文件中的图书信息同步到info数组:
void load_books_info() {
    FILE *ptr = fopen("books info.txt", "r");
    if (ptr == NULL) return;
    int total = numofbooks(ptr);
    rewind(ptr); // 重置文件指针到开头
    char buf[200];
    for (int i = 0; i < total; i++) {
        // 逐行读取解析数据存入结构体
        fgets(buf, sizeof(buf), ptr);
        sscanf(buf, "Book name: %[^\n]", info[i].bname);
        fgets(buf, sizeof(buf), ptr);
        sscanf(buf, "Book author: %[^\n]", info[i].bauthor);
        fgets(buf, sizeof(buf), ptr);
        sscanf(buf, "Number of pages: %u", &info[i].bpages);
        fgets(buf, sizeof(buf), ptr);
        sscanf(buf, "Price (in EGP): %u", &info[i].price);
        fgets(buf, sizeof(buf), ptr);
        sscanf(buf, "Number of books available: %u", &info[i].numavail);
        fgets(buf, sizeof(buf), ptr); // 跳过分割线
    }
    fclose(ptr);
}
  1. 修复searchauthor函数逻辑:
void searchauthor() {
    char in_name[100]; // 长度和结构体中bauthor字段匹配
    int flag = 1;
    // 先加载文件数据到info数组
    load_books_info();
    FILE *ptr = fopen("books info.txt", "r");
    if (ptr == NULL) {
        printf("无法打开图书文件\n");
        return;
    }
    int num = numofbooks(ptr);
    fclose(ptr);
    printf("Enter the name of the author: ");
    // 替换gets为fgets,避免缓冲区溢出
    fgets(in_name, sizeof(in_name), stdin);
    // 去掉fgets读取到的末尾换行符
    in_name[strcspn(in_name, "\n")] = '\0';
    for (int i = 0; i < num; i++) {
        if (strcmpi(in_name, info[i].bauthor) == 0) {
            printf("书名:%s 价格:%u EGP 库存:%u 页数:%u\n", info[i].bname, info[i].price, info[i].numavail, info[i].bpages);
            flag = 0;
        }
    }
    if (flag == 1) {
        printf("Not found.");
    }
}

其他优化建议

  • 不要调用fflush(stdin),该行为是C标准未定义的,处理输入残留换行可以用while(getchar()!='\n');替代
  • 程序启动时就调用一次load_books_info,避免每次操作都重复读取文件

内容的提问来源于stack exchange,提问作者Ali Elneklawy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:48:01