我正在尝试通过以下类型创建学生数据库:(班级学生)
class Student {
unsigned Id;//ID number
char* name;// dynamic memory allocated name (size: 10)
char* family;// dynamic memory allocated last name (size: 10)
int gen;//gender
unsigned MiddleTestGrade;// grade of the student in the middle test
unsigned FinalTestGrade;// grade of the student in the final test
double TotalGrade;// total grade of the student calculates automaticly (dont need to insert this as input)
};
我使用以下命令将所有这些信息写入二进制文件:( StudentData类型是上面提到的Student类)
file.write(reinterpret_cast<const char*>(&StudentData),sizeof(Student));
当我使用read命令从文件中获取所有数据时:
file.read(reinterpret_cast<char*>(&StudentData),sizeof (Student));
结果是除了动态分配的名称之外,一切都很好。它们只包含我写入文件的姓氏。
例如,在我将2名学生插入文件后:
12 Jhon Sna 1 95 100
和
77 David Gen 1 80 85
阅读和打印的结果将是:
12 David Gen 1 95 100
和
77 David Gen 1 80 85
当我使用字符串(不是动态分配)时,一切都应该如下:\
我做错了什么?
答案 0 :(得分:1)
如果在struct
中动态分配数据,则无法使用
file.write(reinterpret_cast<const char*>(&StudentData),sizeof(Student));
将所有数据写入文件中。这只会将结构中指针的二进制值写入文件。当您还原它们时,您将只恢复二进制值,这将导致不可预测的行为。
当有动态分配的数据并适当地读取它们时,您需要分别编写struct
的每个字段。
编写Student
的代码:
// Write Id
file.write(reinterpret_cast<const char*>(&(StudentData.Id)), sizeof(StudentData.Id));
// Get the length of name
// Write the length and then the name
size_t len = strlen(StudentData,name);
file.write(reinterpret_cast<const char*>(&len), sizeof(len));
file.write(StudentData.name, len);
// Get the length of family
// Write the length and then the family
len = strlen(StudentData,family);
file.write(reinterpret_cast<const char*>(&len), sizeof(len));
file.write(StudentData.family, len);
// Write the rest of the data
file.write(reinterpret_cast<const char*>(&(StudentData.gen)), sizeof(StudentData.gen);
file.write(reinterpret_cast<const char*>(&(StudentData.MiddleTestGrade)), sizeof(StudentData.MiddleTestGrade));
file.write(reinterpret_cast<const char*>(&(StudentData.FinalTestGrade)), sizeof(StudentData.FinalTestGrade));
file.write(reinterpret_cast<const char*>(&(StudentData.TotalGrade)), sizeof(StudentData.TotalGrade));
您必须一次读回一个字段的数据,并根据需要分配内存。
// Read the Id.
file.read(reinterpret_cast<char*>(&StudentData.Id),sizeof (Student.Id));
// Read length of the name
size_t len;
file.read(reinterpret_cast<char*>(&len), sizeof (len));
// Allocate memory for name.
Student.name = new char[len+1];
// Read the name and null-terminate it.
file.read(Student.name, len);
Student.name[len] = '\0';
// Read length of the family
file.read(reinterpret_cast<char*>(&len), sizeof (len));
// Allocate memory for family.
Student.family= new char[len+1];
// Read the family and null-terminate it.
file.read(Student.family, len);
Student.family[len] = '\0';
// Read the rest of the Student data
file.read(reinterpret_cast<char*>(&StudentData.gen),sizeof (Student.gen));
file.read(reinterpret_cast<char*>(&StudentData.MiddleTestGrade),sizeof (Student.MiddleTestGrade));
file.read(reinterpret_cast<char*>(&StudentData.FinalTestGrade),sizeof (Student.FinalTestGrade));
file.read(reinterpret_cast<char*>(&StudentData.TotalGrade),sizeof (Student.TotalGrade));