C++二进制文件写入:Student对象写入字节数计算疑问
正确计算Student对象二进制写入的字节数方法
原代码直接使用sizeof(Student)是错误的——因为C++的std::string是动态分配内存的容器,结构体中仅存储了指向字符串数据的指针、当前长度、容量等固定大小的元数据,而非实际的字符串内容。sizeof(Student)返回的是编译期确定的固定值,和每个Student对象中name的实际长度无关,直接写入会导致字符串内容丢失,读取时出现无效内存访问。
要正确确定每个对象的写入字节数,需要手动序列化结构体的每个成员,分步骤计算并写入:
- 处理固定大小的成员:对于
roll_no这种固定类型(int),直接写入其固定字节数sizeof(int)即可。 - 处理动态长度的string成员:字符串需要分两部分写入:
- 先写入字符串的实际长度(用
size_t类型存储),字节数为sizeof(size_t); - 再写入字符串的原始字符数据,字节数为
name.size()。
- 先写入字符串的实际长度(用
每个Student对象的总写入字节数为:sizeof(int) + sizeof(size_t) + name.size()。
示例写入代码
#include <fstream> #include <string> struct Student { int roll_no; std::string name; }; int main() { Student students[] = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}}; std::ofstream outfile("students.bin", std::ios::binary); for (const auto& student : students) { // 写入学号 outfile.write(reinterpret_cast<const char*>(&student.roll_no), sizeof(int)); // 写入名字长度 const size_t name_length = student.name.size(); outfile.write(reinterpret_cast<const char*>(&name_length), sizeof(size_t)); // 写入名字内容 outfile.write(student.name.data(), name_length); } outfile.close(); return 0; }
对应读取逻辑(需匹配写入规则)
为了正确还原数据,读取时也要遵循相同的顺序:
#include <fstream> #include <string> struct Student { int roll_no; std::string name; }; int main() { std::ifstream infile("students.bin", std::ios::binary); Student student; while (infile) { // 读取学号 infile.read(reinterpret_cast<char*>(&student.roll_no), sizeof(int)); if (!infile) break; // 读取名字长度 size_t name_length; infile.read(reinterpret_cast<char*>(&name_length), sizeof(size_t)); // 读取名字内容 student.name.resize(name_length); infile.read(&student.name[0], name_length); // 此处可添加对读取到的Student对象的处理逻辑 } infile.close(); return 0; }
内容的提问来源于stack exchange,提问作者Sandeep
相关产品推荐
相关产品推荐

