简体   繁体   English

从二进制文件读取结构到链表导致无限循环

[英]Reading structure from Binary file to Linked List leading to an infinite loop

This is how my structure is constructed这就是我的结构的构造方式

struct dNascimento{

    int day, month, year;

};

struct morada{

    string street;
    int doorNum;
    string postCode;

};

typedef struct student{

    unsigned int id; //Número mecanográfico
    string name;
    string password;
    morada addressStudent;
    string course;
    dNascimento birth;
    int money;

    student* next;

}* studentPointer;

I'm adding student records to the linked list through this function我正在通过此功能将学生记录添加到链接列表中

void addStudent(studentPointer studentToAdd) {

    studentToAdd->next = NULL;

    if (head != NULL) {

        current = head;

        while (current->next != NULL)
            current = current->next;

        current->next = studentToAdd;


    }
    else
        head = studentToAdd;

}

This is the function I use to save the students in the linked list to the binary file这是我用来将链表中的学生保存到二进制文件的函数

void saveStudentsToFile() {

    FILE *file = fopen("records.bin", "wb");

    if (file != NULL) {

        if (head != NULL) {

            current = head;
            int numberOfStudents = 0;

            while (current != NULL){

                if (fwrite(current, sizeof(student), 1, file) != 1)
                    cout << "\n\t> Erro ao guardar o aluno " << current->name << " no ficheiro!\n" << endl;

                current = current->next;
                numberOfStudents++;

            };

            cout << "\n\t> " << numberOfStudents << " aluno(s) guardados com sucesso!\n" << endl;
            //^ Number of students saved successfully
            fclose(file);

        }else
            cout << "\n\t> Não há registos de alunos para guardar!\n" << endl;
            //^ There are no students to save to the file
    }else
        cout << "\n\t> Erro ao abrir o ficheiro para guardar registo de alunos!\n" << endl;
        //^ Error opening file to save students
}

This is the method I'm using to load the students saved from the file to the linked list这是我用来将文件中保存的学生加载到链表的方法

void loadFile() {

    FILE *file = fopen("records.bin", "rb");

    if (file != NULL) {

        studentPointer studentReader = new student;
        studentReader = (studentPointer) malloc(sizeof(student));
        int numberOfStudentsLoaded = 0;

        while (!(fread(studentReader, sizeof(student), 1, file) != 1)){
                addStudent(studentReader);
                numberOfStudentsLoaded++;
        };

        fclose(file);

        cout << "\n\t> " << numberOfStudentsLoaded << " aluno(s) carregado(s) com sucesso!\n" << endl;
        //^ Number of students loaded successfully
    }
    else
        cout << "\n\t> Erro ao abrir o ficheiro dos registos!\n" << endl;
        //^ Error opening file to load records
}

This is the method I'm using to list the students in the linked list这是我用来在链表中列出学生的方法

void listStudents() {

    if (head != NULL) {

        current = head;
        while (current != NULL) {
            cout << "\n\t> ID #" << current->id << endl;
            cout << "\t> " << current->name << endl;
            cout << "\t> " << current->password << endl;
            current = current->next;
        };

    }
    else
        cout << "\n\t> Não tem registos guardados!\n" << endl;
        //^ No records saved to display
}

When I add records manually to the linked list and use listStudents() to display them, they show up perfectly, but when I save the student records to the binary file and load them, the listStudents() method goes on an infinite loop to only display the last record saved in the binary file.当我手动将记录添加到链表并使用listStudents()显示它们时,它们显示得很好,但是当我将学生记录保存到二进制文件并加载它们时, listStudents()方法会无限循环显示保存在二进制文件中的最后一条记录。

Keep in mind that every variable in the structure is correctly initialized before saved.请记住,结构中的每个变量在保存之前都已正确初始化。

How students show up through listStudents() when I insert them manually http://image.prntscr.com/image/73459c40d81d462ca043ee414d1556d0.png当我手动插入学生时,学生如何通过listStudents()出现http://image.prntscr.com/image/73459c40d81d462ca043ee414d1556d0.png

How students show up after I saveStudentsToFile() and loadFile() http://image.prntscr.com/image/c3dfb61235de46b7adb757d0762883a9.pngsaveStudentsToFile()loadFile()后学生如何出现http://image.prntscr.com/image/c3dfb61235de46b7adb757d0762883a9.png

One of the problems with your code is that you cannot use fread to read student data from file (the same applies to fwrite ).您的代码的问题之一是您不能使用fread从文件中读取student数据(这同样适用于fwrite )。 Your student class is not POD (Plain Old Data), it contains string variables which cannot be initialized by reading from binary file with fread.您的学生类不是 POD(普通旧数据),它包含无法通过使用 fread 从二进制文件读取来初始化的string变量。 You should use fstream to write field by field to output file, and then read field by field.您应该使用fstream逐字段写入输出文件,然后逐字段读取。 Or convert your student struct to POD, ie: replace all string name;或者将你的student struct 转换为POD,即:替换所有string name; with char name[64];char name[64]; . .

Also, if you store: student* next;另外,如果您存储: student* next; then you should not use its value, address will not be valid.那么你不应该使用它的值,地址将无效。

Your code looks more like C than C++, for example here:您的代码看起来更像 C 而不是 C++,例如这里:

Why do you:你为什么:

    studentPointer studentReader = new student;
    studentReader = (studentPointer) malloc(sizeof(student));

you dont need (studentPointer) malloc(sizeof(student));你不需要(studentPointer) malloc(sizeof(student)); . . Whats more you should not use malloc as it will not call constructors for string variables.更重要的是,您不应该使用malloc因为它不会为string变量调用构造函数。

In the end never ending loop is probably caused by Undefined Behaviours in your code.最后,永无止境的循环可能是由代码中的未定义行为引起的。

[edit] [编辑]

The reason for infinite loop is because you dont allocate each time you read a student from file, so you end up with all the same students.无限循环的原因是因为每次从文件中读取学生时都没有分配,因此最终得到的都是相同的学生。 Below is corrected code.:以下是更正的代码。:

    int numberOfStudentsLoaded = 0;
    while (true){
            studentReader = (studentPointer) malloc(sizeof(student));

            if ((fread(studentReader, sizeof(student), 1, file) != 1)
               break;

            addStudent(studentReader);
            numberOfStudentsLoaded++;
    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM