《C++避坑神器·七》二进制读写自定义类型导致崩溃或数据读写不全问题

简介: 《C++避坑神器·七》二进制读写自定义类型导致崩溃或数据读写不全问题

概要

二进制读写不仅可以对普通数据类型进行读写,也能对自定义数据类型进行读写,同时对自定义数据类型的读写容易导致读写崩溃或数据不全问题。

技术细节

1、二进制写文件

ofstream ofs; //创建流对象

ofs.open(“文件路径”, 打开方式); //打开文件并判断文件是否打开成功

ofs.write(const char *buffer, int len); //写数据,len表示buffer总字节数

ofs.close() //关闭文件

class Person
{
public:
  Person(const char name[], int age)
  {
    strcpy_s(this->name, name);
    this->age = age;
  }
  char name[30]; //字符串不能用char*或者string类型存放
  int age;
};
int main()
{
  //创建流对象并打开文件
  ofstream ofs("D:\\test.txt", ios::binary|ios::out);
  //判断文件是否打开成功
  if (!ofs.is_open())
  {
    cout << "文件打开失败!" << endl;
    return 0;
  }
  //写数据
  Person p("张三", 20);
  ofs.write((const char*)&p, sizeof(Person)); //强转const char*
  //关闭文件
  ofs.close();
}

2、二进制读文件

read(char *buffer, int len) //len为buffer总字节数

class Person
{
public:
  char name[30]; //字符串不能用char*或者string类型存放
  int age;
};
int main()
{
  //创建流对象并打开文件
  ifstream ifs("D:\\test.txt", ios::binary|ios::in);
  //判断文件是否打开成功
  if (!ifs.is_open())
  {
    cout << "文件打开失败!" << endl;
    return 0;
  }
  //读数据
  Person p;
  ifs.read((char*)&p, sizeof(Person));
  cout << p.name << " " << p.age << endl; //张三,20
  //关闭文件
  ifs.close();
}

小结

二进制读写成员变量的字符串为啥不设为string或char *类型,拿char 举例,char 指向一个字符串地址,假设这个字符串内容占10个字节,写到文本后内容是占10个字节的,在读取的时候sizeof(Person)不是10个字节,而是四个字节(指针占四个字节),这样的话10个字节的内容就读不全,那输出char内容可能就是乱码或者错误的结果。string类仅有一个数据成员,char指针,故string类的大小和指针相似,所以最好采取char name[]的字符数组形式。

相关文章
|
4月前
|
存储 C++
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
105 1
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
|
4月前
|
存储 算法 C++
C++ STL应用宝典:高效处理数据的艺术与实战技巧大揭秘!
【8月更文挑战第22天】C++ STL(标准模板库)是一组高效的数据结构与算法集合,极大提升编程效率与代码可读性。它包括容器、迭代器、算法等组件。例如,统计文本中单词频率可用`std::map`和`std::ifstream`实现;对数据排序及找极值则可通过`std::vector`结合`std::sort`、`std::min/max_element`完成;而快速查找字符串则适合使用`std::set`配合其内置的`find`方法。这些示例展示了STL的强大功能,有助于编写简洁高效的代码。
54 2
|
4月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
4月前
|
存储 数据挖掘 C语言
【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】
【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】
|
4月前
|
存储 安全 数据处理
【C++】C++ 超市会员卡管理系统(面向对象)(源码+数据)【独一无二】
【C++】C++ 超市会员卡管理系统(面向对象)(源码+数据)【独一无二】
108 1
|
5月前
|
机器学习/深度学习 算法 C++
C++多态崩溃问题之为什么在计算梯度下降时需要除以批次大小(batch size)
C++多态崩溃问题之为什么在计算梯度下降时需要除以批次大小(batch size)
|
5月前
|
设计模式 监控 Go
开发与运维C++问题之C++部分原有的数据发送能力如何解决
开发与运维C++问题之C++部分原有的数据发送能力如何解决
27 1
|
4月前
|
存储 算法 C++
【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】
【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】
|
25天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
38 2
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
83 5