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

C语言图书管理系统问题:添加多本书后仅显示最后一本信息

问题分析与解决方案

你的图书管理系统添加多本后只显示最后一本,核心原因是所有图书记录都指向了同一块内存空间——每次添加时你都在覆盖同一个结构体变量的数据,而非为每本图书分配独立存储。

常见错误代码示例(对应你的问题)

假设你的代码类似这样:

#include <stdio.h>
#include <string.h>

typedef struct {
    char name[50];
    char author[50];
    float price;
    int pages;
} Book;

Book book; // 单个结构体变量,被重复覆盖
Book *books[100];
int count = 0;

void addBook() {
    printf("书名:");
    scanf("%s", book.name);
    printf("作者:");
    scanf("%s", book.author);
    printf("价格:");
    scanf("%f", &book.price);
    printf("页数:");
    scanf("%d", &book.pages);
    books[count++] = &book; // 每次都存同一个地址
}

void displayBooks() {
    for (int i = 0; i < count; i++) {
        printf("图书%d:%s | %s | %.2f | %d\n", 
               i+1, books[i]->name, books[i]->author, books[i]->price, books[i]->pages);
    }
}

int main() {
    addBook();
    addBook();
    displayBooks();
    return 0;
}

这里book是全局/局部的单个变量,每次调用addBook都会覆盖它的内容,books数组里存的都是同一个&book地址,所以显示时所有条目都指向最后一次输入的数据。

两种修正方案

方案1:使用固定大小的结构体数组(适合已知最大图书数量的场景)

直接用数组存储每本图书的结构体,每本图书占用独立的数组元素:

#include <stdio.h>
#include <string.h>

#define MAX_BOOKS 100 // 设定最大存储数量

typedef struct {
    char name[50];
    char author[50];
    float price;
    int pages;
} Book;

Book books[MAX_BOOKS];
int count = 0;

void addBook() {
    if (count >= MAX_BOOKS) {
        printf("已达最大存储上限,无法添加新图书\n");
        return;
    }
    printf("书名:");
    scanf("%s", books[count].name);
    printf("作者:");
    scanf("%s", books[count].author);
    printf("价格:");
    scanf("%f", &books[count].price);
    printf("页数:");
    scanf("%d", &books[count].pages);
    count++; // 计数加1,下一本存在下一个数组位置
}

void displayBooks() {
    for (int i = 0; i < count; i++) {
        printf("图书%d:%s | %s | %.2f | %d\n", 
               i+1, books[i].name, books[i].author, books[i].price, books[i].pages);
    }
}

int main() {
    addBook();
    addBook();
    displayBooks();
    return 0;
}

方案2:使用动态内存分配(适合不确定最大数量的场景)

通过malloc为每本图书分配独立内存,再用realloc扩展存储指针的数组:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
    char name[50];
    char author[50];
    float price;
    int pages;
} Book;

Book **books = NULL; // 存储图书指针的动态数组
int count = 0;

void addBook() {
    // 为新图书分配内存
    Book *newBook = (Book*)malloc(sizeof(Book));
    if (!newBook) {
        printf("内存分配失败,无法添加图书\n");
        return;
    }
    printf("书名:");
    scanf("%s", newBook->name);
    printf("作者:");
    scanf("%s", newBook->author);
    printf("价格:");
    scanf("%f", &newBook->price);
    printf("页数:");
    scanf("%d", &newBook->pages);
    
    // 扩展指针数组的容量
    Book **temp = (Book**)realloc(books, (count + 1) * sizeof(Book*));
    if (!temp) {
        printf("数组扩容失败,已释放当前图书内存\n");
        free(newBook);
        return;
    }
    books = temp;
    books[count++] = newBook;
}

void displayBooks() {
    for (int i = 0; i < count; i++) {
        printf("图书%d:%s | %s | %.2f | %d\n", 
               i+1, books[i]->name, books[i]->author, books[i]->price, books[i]->pages);
    }
}

// 记得释放动态分配的内存,避免泄漏
void freeBooks() {
    for (int i = 0; i < count; i++) {
        free(books[i]);
    }
    free(books);
}

int main() {
    addBook();
    addBook();
    displayBooks();
    freeBooks();
    return 0;
}

核心要点

  • 每本图书必须拥有独立的内存空间,不能复用同一个结构体变量
  • 固定数组实现简单,适合场景明确的情况;动态分配更灵活,但需要注意内存释放
  • 调试时可以打印每个图书记录的地址,确认是否指向不同内存区域

内容的提问来源于stack exchange,提问作者Omar Ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 17:05:59