从二进制文件中读取动态内存分配的字符串(char*)

read dynamic memory allocated string (char*) from binary file C++

本文关键字:字符串 char 分配 二进制文件 读取 动态 内存      更新时间:2023-10-16

我想让学生数据库通过这种类型:(类学生)

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 jhn Sna 1 95 100

77 David Gen 1 80 85

读取和打印的结果将是:

12 David Gen 1 95 100

77 David Gen 1 80 85

当我使用字符串(不是动态分配)时,一切都像它应该的那样工作:

我做错了什么?

当您在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] = '';
// 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] = '';
// 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));
相关文章: