图书管理系统c语言文件读取错误

img

img


图书管理系统从文件中的读取有错误,我不知道怎么改,而且图书管理系统只能运行一次,就卡在读取文件的界面,求速教

用fscanf读,写法和fprintf差不多

img

img


会显示已停止工作,然后文件里不知道为什么多了一个数字,就是第一行那个,是我其他程序的问题吗

代码的问题,主要在 void loadFromFile() 函数里,问题见注释,另 void saveToFile() 函数也做了修改,其它没什么问题,供参考:

void saveToFile()
{
    FILE *fp;
    fp = fopen("book.txt", "wt"); //fp = fopen("book.txt", "a+");  修改 文件的打开方式
    if (fp == NULL) {
        printf("打开文件失败\n");
        return;
    }
    fprintf(fp,"%d\n",indexList->totalBooks);// 写入书籍总数
    for(int i = 0; i < indexList->totalBooks; i++) // 写入每一本书籍的信息
    fprintf(fp,"%d\t%s\t%s\t%d\t%d\n",indexList->books[i].bookNum,indexList->books[i].name,
             indexList->books[i].author,indexList->books[i].total,indexList->books[i].stock);
    printf("数据保存成功!\n");
    fclose(fp);
}
void loadFromFile()
{
    FILE *fp;
    fp = fopen("book.txt", "rt"); //fp = fopen("book.txt", "a+");  修改 文件的打开方式
    if (fp == NULL) {
        printf("打开文件失败\n");
        return;
    }
    fscanf(fp,"%d\n",&indexList->totalBooks); // 读取书籍总数
    printf("读取书籍总数为%d\n", indexList->totalBooks);
    for (int i = 0; i < indexList->totalBooks; i++)// 读取每一本书籍的信息
    {
        fscanf(fp,"%d\t%s\t%s\t%d\t%d\n",&indexList->books[i].bookNum,indexList->books[i].name,//第一个参数的格式错误
      //fscanf(fp,"%s\t%s\t%s\t%d\t%d\n",indexList->books[i].bookNum,indexList->books[i].name, //应将 %s 修改为:%d
              indexList->books[i].author,&indexList->books[i].total,&indexList->books[i].stock);
    }
    printf("读取数据成功!\n");
    fclose(fp);
}

整体代码修改如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_BOOKS 200
#define MAX_BOOK_NAME 50
#define MAX_AUTHOR_NAME 30
// 书籍结构体
struct Book
{
    int bookNum;                    // 书号
    char name[MAX_BOOK_NAME];       // 书名
    char author[MAX_AUTHOR_NAME];   // 作者
    int total;                      // 现存量
    int stock;                      // 库存量
}Book;// 线性表结构体
struct Index
{
    struct Book books[MAX_BOOKS];  // 书籍数组
    int totalBooks;                // 书籍总数
};
struct Index *indexList;// 线性表指针

void initIndexList();//初始化线性表
void addBook();//采编入库
void borrowBook();//借阅
void returnBook();//归还
void queryBook();//查询书籍
void displayAllBooks();//输出所有书籍信息
void saveToFile();//保存数据到文件
void loadFromFile();//从文件中读取数据
void quit();//退出程序
void showMenu();//显示菜单
void initIndexList() 
{
    indexList = (struct Index *)malloc(sizeof(struct Index));// 分配内存
    indexList->totalBooks = 0;// 初始化书籍总数为0
}
void addBook() 
{
    int bookNum, total;
    char name[MAX_BOOK_NAME], author[MAX_AUTHOR_NAME];
    printf("请输入书号:");
    scanf("%d", &bookNum);
    for (int i = 0; i < indexList->totalBooks; i++) 
    {
        if (indexList->books[i].bookNum == bookNum) 
        {
            printf("该书已存在,现存量为%d\n", indexList->books[i].total);
            printf("请输入需要增加的库存量:");
            scanf("%d", &total);
            indexList->books[i].stock += total;
            indexList->books[i].total += total;
            printf("增加库存成功!\n");
            return;
        }
    }
    printf("请输入书名:");
    scanf("%s", name);
    printf("请输入作者:");
    scanf("%s", author);
    printf("请输入现存量:");
    scanf("%d", &total);
    if (indexList->totalBooks >= MAX_BOOKS) // 判断书籍总数是否超过MAX_BOOKS
    {
        printf("添加书籍失败,书籍总数已经达到上限\n");
        return;
    }
    indexList->books[indexList->totalBooks].bookNum = bookNum;// 添加书籍到线性表
    strcpy(indexList->books[indexList->totalBooks].name, name);
    strcpy(indexList->books[indexList->totalBooks].author, author);
    indexList->books[indexList->totalBooks].total = total;
    indexList->books[indexList->totalBooks].stock = total;
    indexList->totalBooks++;
    printf("添加书籍成功!\n");
}
void borrowBook() 
{
    int bookNum;
    printf("请输入借阅的书号:");
    scanf("%d", &bookNum);
    for (int i = 0; i < indexList->totalBooks; i++)
    {
        if (indexList->books[i].bookNum == bookNum) 
        {
            if (indexList->books[i].total <= 0) {
                printf("借阅失败,该书已经无库存\n"); 
                return;
            }
            indexList->books[i].total--;// 借阅成功,修改书籍信息
            printf("借阅成功,请在15天内归还\n");
            return;
        }
    }
    printf("借阅失败,找不到该书\n");
}
void returnBook() 
{
    int bookNum;
    printf("请输入归还的书号:");
    scanf("%d", &bookNum);
 
    for (int i = 0; i < indexList->totalBooks; i++) 
    {
        if (indexList->books[i].bookNum == bookNum) 
        {
            // 修改书籍信息
            indexList->books[i].total++;
            printf("归还成功!\n");
            return;
        }
    }
    printf("归还失败,找不到该书\n");
}
void queryBook() 
{
    int bookNum;
    printf("请输入要查询的书号:");
    scanf("%d", &bookNum);
    for (int i = 0; i < indexList->totalBooks; i++) 
    {
        if (indexList->books[i].bookNum == bookNum) {
            printf("书号:%d,书名:%s,作者:%s,现存量:%d,库存量:%d\n", indexList->books[i].bookNum,
                   indexList->books[i].name, indexList->books[i].author, indexList->books[i].total,
                   indexList->books[i].stock);
            return;
        }
    }
    printf("找不到该书\n");
}
void displayAllBooks() 
{
    for (int i = 0; i < indexList->totalBooks; i++) {
        printf("书号:%d,书名:%s,作者:%s,现存量:%d,库存量:%d\n", indexList->books[i].bookNum,
               indexList->books[i].name, indexList->books[i].author, indexList->books[i].total,
               indexList->books[i].stock);
    }
}
void saveToFile()
{
    FILE *fp;
    fp = fopen("book.txt", "wt"); //fp = fopen("book.txt", "a+");  修改 文件的打开方式
    if (fp == NULL) {
        printf("打开文件失败\n");
        return;
    }
    fprintf(fp,"%d\n",indexList->totalBooks);// 写入书籍总数
    for(int i = 0; i < indexList->totalBooks; i++) // 写入每一本书籍的信息
    fprintf(fp,"%d\t%s\t%s\t%d\t%d\n",indexList->books[i].bookNum,indexList->books[i].name,
             indexList->books[i].author,indexList->books[i].total,indexList->books[i].stock);
    printf("数据保存成功!\n");
    fclose(fp);
}
void loadFromFile()
{
    FILE *fp;
    fp = fopen("book.txt", "rt"); //fp = fopen("book.txt", "a+");  修改 文件的打开方式
    if (fp == NULL) {
        printf("打开文件失败\n");
        return;
    }
    fscanf(fp,"%d\n",&indexList->totalBooks); // 读取书籍总数
    printf("读取书籍总数为%d\n", indexList->totalBooks);
    for (int i = 0; i < indexList->totalBooks; i++)// 读取每一本书籍的信息
    {
        fscanf(fp,"%d\t%s\t%s\t%d\t%d\n",&indexList->books[i].bookNum,indexList->books[i].name,//第一个参数的格式错误
      //fscanf(fp,"%s\t%s\t%s\t%d\t%d\n",indexList->books[i].bookNum,indexList->books[i].name, //应将 %s 修改为:%d
              indexList->books[i].author,&indexList->books[i].total,&indexList->books[i].stock);
    }
    printf("读取数据成功!\n");
    fclose(fp);
}
void quit()
{
    saveToFile();// 保存数据到文件
    printf("感谢使用图书管理系统,再见!\n");
    free(indexList);  // 释放内存
    exit(0);
}
void showMenu() 
{
    int choice;
    while (1) {
        printf("\n");
        printf("图书管理系统菜单\n");
        printf("===================\n");
        printf("1、采编入库\n");
        printf("2、借阅\n");
        printf("3、归还\n");
        printf("4、查询\n");
        printf("5、显示所有书籍信息\n");
        printf("6、退出系统\n");
 
        printf("请输入您的选择(1-6):");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                addBook();
                break;
            case 2:
                borrowBook();
                break;
            case 3:
                returnBook();
                break;
            case 4:
                queryBook();
                break;
            case 5:
                displayAllBooks();
                break;
            case 6:
                quit();
                break;
            default:
                printf("输入无效,请重新输入\n");
                break;
        }
    }
}
int main() 
{
    initIndexList();// 初始化线性表
    loadFromFile();// 从文件中读取数据
    showMenu();  // 显示菜单
    return 0;
}