如果我想要将L_student类型中的data数据一次性读取到文件中去,该如何做?我下面读写的方法感觉也是错误的,该如何修改?

L_student是LinkList_student*类型的链表
该函数作用是将L_student链表中的信息读取到文件中去,但是L_student类型包含基本类型和结构体数组,如果我想要将L_student类型中的data数据一次性读取到文件中去,该如何做?我下面读写的方法感觉也是错误的,该如何修改?

void saveInfoToFile_student(const char* FileName)
{
    FILE* pf = fopen(FileName, "w");
    LinkList_student* pMove = L_student->next;
    while (pMove != NULL)
    {
        fprintf(pf, "%d\t%s\t%s\t%s\t%d\n", pMove->data.account, pMove->data.password, pMove->data.name,
            pMove->data.student_number, pMove->data.num);
        fwrite(&pf, sizeof(Book), 1, pf);
    }
}
 

结构体代码:

typedef struct//定义书结构体
{
    char name[MAX];//书名
    char number[MAX];//书的编号
    int price;//书的价格
    int num;//书的数量
}Book;
 
typedef struct//定义学生账号结构体
{
    int account;//账号
    char password[MAX];//密码
    char name[MAX];//姓名
    char student_number[MAX];//学号
    int num;//借书数量
    Book book[10];//借的书,并且最多只能借10本
}Student;
 
typedef struct Node//定义书链表
{
    Book data;
    struct Node* next;
}LinkList_book;
 
typedef struct Node1//定义学生账户链表
{
    Student data;
    struct Node1* next;
}LinkList_student;
 

这么改,供参考:

#include <stdio.h>
#include <stdlib.h>
#define MAX 12
typedef struct//定义书结构体
{
    char name[MAX];//书名
    char number[MAX];//书的编号
    int price;//书的价格
    int num;//书的数量
}Book;
 
typedef struct//定义学生账号结构体
{
    int account;//账号
    char password[MAX];//密码
    char name[MAX];//姓名
    char student_number[MAX];//学号
    int num;//借书数量
    Book book[10];//借的书,并且最多只能借10本
}Student;
 
typedef struct Node//定义书链表
{
    Book data;
    struct Node* next;
}LinkList_book;
 
typedef struct Node1//定义学生账户链表
{
    Student data;
    struct Node1* next;
}LinkList_student;

LinkList_student* L_student;

void saveInfoToFile_student(const char* FileName)
{
    FILE* pf = fopen(FileName, "w");
    LinkList_student* pMove = L_student->next;
    while (pMove != NULL)
    {
        //fprintf(pf, "%d\t%s\t%s\t%s\t%d\n", pMove->data.account, pMove->data.password,
        //                  pMove->data.name,pMove->data.student_number, pMove->data.num);
        //fwrite(&pf, sizeof(Book), 1, pf);
        fwrite(&pMove->data, sizeof(Student),1, pf);
        pMove = pMove->next;
    }
}

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    是的,我理解您的问题。

    针对这个问题,我的建议是使用二进制方式读写数据,这比使用文本方式快得多,并且可以轻松地将LinkList_student*类型的data数据一次性读写到文件中去。

    具体实现步骤如下:

    1. 定义一个二进制文件写入函数write_binary_file(),该函数接收两个参数:文件名和LinkList_student*类型的指针。
    void write_binary_file(const char* filename, LinkList_student* students) {
        // 打开文件,以二进制方式写入
        FILE* fp = fopen(filename, "wb");
    
        // 写入链表的长度
        int length = length_of_linklist(students);
        fwrite(&length, sizeof(int), 1, fp);
    
        // 写入链表中每个学生的数据
        while (students != NULL) {
            // 写入基本类型的数据
            fwrite(&(students->id), sizeof(int), 1, fp);
            fwrite(&(students->name), sizeof(char), MAX_NAME_LEN, fp);
            fwrite(&(students->age), sizeof(int), 1, fp);
    
            // 写入结构体数组的数据
            fwrite(students->data, sizeof(Student_Data), DATA_ARRAY_SIZE, fp);
    
            students = students->next;
        }
    
        // 关闭文件
        fclose(fp);
    }
    
    1. 定义一个二进制文件读取函数read_binary_file(),该函数接收一个参数:文件名,返回值为LinkList_student*类型的指针。
    LinkList_student* read_binary_file(const char* filename) {
        // 打开文件,以二进制方式读取
        FILE* fp = fopen(filename, "rb");
    
        // 读取链表的长度
        int length;
        fread(&length, sizeof(int), 1, fp);
    
        // 创建链表头节点
        LinkList_student* head = create_linklist();
    
        // 读取链表中每个学生的数据,并添加到链表末尾
        LinkList_student* tail = head;
        for (int i = 0; i < length; i++) {
            // 创建一个新节点
            LinkList_student* new_node = create_new_node();
    
            // 读取基本类型的数据
            fread(&(new_node->id), sizeof(int), 1, fp);
            fread(&(new_node->name), sizeof(char), MAX_NAME_LEN, fp);
            fread(&(new_node->age), sizeof(int), 1, fp);
    
            // 读取结构体数组的数据
            fread(new_node->data, sizeof(Student_Data), DATA_ARRAY_SIZE, fp);
    
            // 将新节点添加到链表末尾
            tail = add_new_node_to_tail(tail, new_node);
        }
    
        // 关闭文件
        fclose(fp);
    
        return head;
    }
    

    其中,length_of_linklist()、create_new_node()、create_linklist()、add_new_node_to_tail()等函数需要根据您的实际代码进行实现。

    这种方式的优点是可以将整个链表的数据一次性读写到文件中,速度非常快,并且数据在文件中的存储也非常紧凑,不会出现文本方式下的数据冗余和格式问题。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^