如何正确使用缓冲区操作二进制文件——实现string向量的二进制文件读写
正确实现vector二进制读写的方法
我来帮你梳理下代码里的问题,然后给出正确的实现方式。你的代码里有几个关键错误导致无法正确读写二进制文件:
- 写入逻辑完全颠倒:你在
if (!bin_out.is_open())代码块里执行写入操作,这意味着只有文件打不开的时候才会尝试写入——这完全搞反了逻辑!应该是文件成功打开后才执行写入,打不开则报错退出。 - 错误的指针转换:写入
vec.size()和字符串长度时,你直接把数值强制转换成char*,这会把数值当成内存地址来访问,直接触发未定义行为。正确的做法是取变量的地址再转成char*。 - 类型不匹配:
vec.size()返回的是size_t类型(无符号整数),但你用int来处理,读写时类型不统一会导致数据错乱。 - 未初始化的缓冲区:读取时的
char* buffer没有分配内存就直接使用,会导致内存访问错误,其实完全不需要用这种方式,直接读取到对应类型的变量里更安全。
修正后的完整代码
#include <iostream> #include <fstream> #include <string> #include <vector> using namespace std; void write_bin() { vector<string> vec = {"Text1", "Text2", "Text3", "Text4"}; ofstream bin_out("binary.bin", ios::binary | ios::out | ios::trunc); // 先检查文件是否成功打开 if (!bin_out.is_open()) { cerr << "无法打开文件进行写入!" << endl; return; } // 写入vector的元素个数(用size_t保证类型一致) size_t vec_size = vec.size(); bin_out.write(reinterpret_cast<char*>(&vec_size), sizeof(vec_size)); // 逐个写入每个字符串:先写长度,再写内容 for (const string& s : vec) { size_t str_len = s.size(); bin_out.write(reinterpret_cast<char*>(&str_len), sizeof(str_len)); bin_out.write(s.data(), str_len); // s.data()等价于&s[0],更清晰 } bin_out.close(); } void read_bin() { ifstream bin_in("binary.bin", ios::binary | ios::in); // 检查文件是否成功打开 if (!bin_in.is_open()) { cerr << "无法打开文件进行读取!" << endl; return; } vector<string> vec; size_t vec_size; // 先读取vector的元素个数 bin_in.read(reinterpret_cast<char*>(&vec_size), sizeof(vec_size)); // 预分配内存,提升效率 vec.reserve(vec_size); for (size_t i = 0; i < vec_size; ++i) { size_t str_len; // 读取当前字符串的长度 bin_in.read(reinterpret_cast<char*>(&str_len), sizeof(str_len)); // 创建对应长度的空字符串,再读取内容 string s(str_len, '\0'); bin_in.read(&s[0], str_len); vec.push_back(s); cout << s << endl; } bin_in.close(); } int main() { write_bin(); read_bin(); return 0; }
关键注意事项
- 类型一致性:全程用
size_t处理长度和元素个数,避免int和size_t之间的隐式转换导致数据错误。 - 文件检查:读写前一定要确认文件成功打开,否则后续操作都是无效的。
- 安全读写:写入时传递变量的地址(
&var),读取时直接把数据读到对应类型的变量中,不要用未初始化的指针缓冲区。 - 字符串处理:读取字符串时,先获取长度再创建对应大小的字符串,避免缓冲区溢出或内存浪费。
内容的提问来源于stack exchange,提问作者BSlegt
相关产品推荐
相关产品推荐

