将结构从二进制文件读取到链表,导致无限循环
Reading structure from Binary file to Linked List leading to an infinite loop
这就是我的结构构建的方式
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;
我正在通过这个功能将学生记录添加到链接列表中
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;
}
这是我用来将链接列表中的学生保存到二进制文件的功能
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 << "nt> Erro ao guardar o aluno " << current->name << " no ficheiro!n" << endl;
current = current->next;
numberOfStudents++;
};
cout << "nt> " << numberOfStudents << " aluno(s) guardados com sucesso!n" << endl;
//^ Number of students saved successfully
fclose(file);
}else
cout << "nt> Não há registos de alunos para guardar!n" << endl;
//^ There are no students to save to the file
}else
cout << "nt> Erro ao abrir o ficheiro para guardar registo de alunos!n" << endl;
//^ Error opening file to save students
}
这是我用来将学生从文件中保存到链接列表的方法
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 << "nt> " << numberOfStudentsLoaded << " aluno(s) carregado(s) com sucesso!n" << endl;
//^ Number of students loaded successfully
}
else
cout << "nt> Erro ao abrir o ficheiro dos registos!n" << endl;
//^ Error opening file to load records
}
这是我在链接列表中列出学生的方法
void listStudents() {
if (head != NULL) {
current = head;
while (current != NULL) {
cout << "nt> ID #" << current->id << endl;
cout << "t> " << current->name << endl;
cout << "t> " << current->password << endl;
current = current->next;
};
}
else
cout << "nt> Não tem registos guardados!n" << endl;
//^ No records saved to display
}
当我手动将记录添加到链表中并使用listStudents()
显示它们时,它们会完美显示,但当我将学生记录保存到二进制文件并加载它们时,listStudents()
方法会进行无限循环,只显示保存在二进制文件中的最后一条记录。
请记住,结构中的每个变量在保存之前都已正确初始化。
当我手动插入学生时,他们如何通过
listStudents()
显示http://image.prntscr.com/image/73459c40d81d462ca043ee414d1556d0.png学生在I
saveStudentsToFile()
和loadFile()
之后的表现http://image.prntscr.com/image/c3dfb61235de46b7adb757d0762883a9.png
代码的问题之一是无法使用fread
从文件中读取student
数据(fwrite
也是如此)。您的学生类不是POD(纯旧数据),它包含string
变量,这些变量无法通过使用fread从二进制文件中读取来初始化。您应该使用fstream
逐字段写入输出文件,然后逐字段读取。或者将您的学生结构转换为POD,即:用char name[64];
替换所有string name;
。
此外,如果存储:student* next;
,则不应使用其值,地址将无效。
您的代码看起来更像C而不是C++,例如:
为什么:
studentPointer studentReader = new student;
studentReader = (studentPointer) malloc(sizeof(student));
你不需要(studentPointer) malloc(sizeof(student));
。此外,您不应该使用malloc
,因为它不会调用string
变量的构造函数。
最终,永无止境的循环可能是由代码中的未定义行为引起的。
[编辑]
无限循环的原因是,每次从文件中读取一个学生时,你们并没有进行分配,所以你们最终得到的都是相同的学生。以下是更正后的代码。:
int numberOfStudentsLoaded = 0;
while (true){
studentReader = (studentPointer) malloc(sizeof(student));
if ((fread(studentReader, sizeof(student), 1, file) != 1)
break;
addStudent(studentReader);
numberOfStudentsLoaded++;
};
- 使用std::list创建循环链表
- 遍历链表时的无限循环
- 循环链表:无限循环
- 打印循环链表
- C++循环链表删除,计数从下一个节点开始
- C++ 循环链表的递归基本情况
- 循环链表的内存错误:未分配正在释放的指针
- 返回指向循环链表某个点的指针
- 在 for 循环(链表)中删除两次后,变量不可用
- 尝试拆分循环链表.显示输出但崩溃.在 IDEone 中显示运行时错误
- 如何打印出双向循环链表
- 循环队列和循环链表
- 我想在我的代码中实现一个双重循环链表 - 运行时错误
- 用C++打印出循环链表
- 需要帮助编码迭代器的循环链表在c++
- 获取单个非循环链表中指针后面节点的值
- 删除循环链表中的节点
- 循环链表的循环开始节点
- 如何将链表转换为循环链表
- STL deque是作为循环链表实现的