这是我的结构构建方式
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 << "\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
}
这是我用来将从文件中保存的学生加载到链表
的方法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
}
这是我用来列出链表中学生的方法
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
}
当我手动将记录添加到链接列表并使用listStudents()
显示它们时,它们会完美显示,但是当我将学生记录保存到二进制文件并加载它们时,listStudents()
方法进行无限循环以仅显示保存在二进制文件中的最后一条记录。
请记住,在保存之前,结构中的每个变量都已正确初始化。
当我手动插入学生时,学生如何通过
listStudents()
出现 http://image.prntscr.com/image/73459c40d81d462ca043ee414d1556d0.png学生
saveStudentsToFile()
和loadFile()
之后如何出现 http://image.prntscr.com/image/c3dfb61235de46b7adb757d0762883a9.png
答案 0 :(得分:0)
您的代码存在的一个问题是,您无法使用fread
从文件中读取student
数据(同样适用于fwrite
)。您的学生班级不是POD(普通旧数据),它包含string
个变量,这些变量无法通过读取带有fread的二进制文件来初始化。您应该使用fstream
逐字段写入输出文件,然后逐字段读取。或者将您的学生结构转换为POD,即:将所有string name;
替换为char name[64];
。
此外,如果您存储:student* next;
,则不应使用其值,地址将无效。
您的代码看起来更像C而不是C ++,例如:
为什么:
studentPointer studentReader = new student;
studentReader = (studentPointer) malloc(sizeof(student));
你不需要(studentPointer) malloc(sizeof(student));
。更重要的是,您不应该使用malloc
,因为它不会为string
变量调用构造函数。
最后,永无止境的循环可能是由代码中的Undefined Behaviors引起的。
[编辑]
无限循环的原因是因为每次从文件中读取学生时都不会分配,所以最终会得到所有相同的学生。以下是更正后的代码。:
int numberOfStudentsLoaded = 0;
while (true){
studentReader = (studentPointer) malloc(sizeof(student));
if ((fread(studentReader, sizeof(student), 1, file) != 1)
break;
addStudent(studentReader);
numberOfStudentsLoaded++;
};