我有非常简单但巨大的 vector :
struct Vectors //of the same types and the same sizes
{
vector<int> A;
vector<int> B;
vector<int> C;
vector<int> D;
vector<int> E;
vector<int> F;
}
并希望一次性将它们写入二进制文件。
到目前为止,我在以下工具的帮助下成功地将单个 vector 写入和读取到二进制文件:file.write(reinterpret_cast<const char*>(&A[0]), sizeof(A));
, file.read(reinterpret_cast<char*>(&A[0]), sizeof(binaryfile));
我对这 6 个 vector 依次做了同样的事情,但是当我尝试读取二进制文件时,出现错误:vector subscript out of range
问题可能出在自动填充上吗?以及如何克服它? 是否可以一次写入然后读取整个 vector 结构?以便在我内存 mmap 二进制文件后随时可用? 顺便说一句,我不坚持使用 vector ,我可以使用数组或任何更适合我的情况的数据类型......
最佳答案
读取和写入 vector 的整个数据部分的诀窍是在写入数据 block 之前获取数据 block 的大小,然后在读取数据 block 之前获取数据 block 的大小。当然,你阅读时不知道大小,因此大小也需要在文件中。这允许您为 vector 分配那么多空间,然后读取那么多数据。
这是一种可能的实现方式。我走了捷径。您的文件头可能应该有一个可以检查的标识符,这样您就知道您正在阅读一个声称正确遵循您的布局的文件。你真的,真的需要检查文件是否打开和读/写工作。而且我没有为我的 operator==() 编写测试,我用它来测试加载/保存对(尽管我确实检查了一次调试器中的值)。
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>
struct Vectors {
std::vector<int> A, B, C, D, E, F;
bool save(const char * filename);
bool load(const char * filename);
bool operator == (const Vectors &rhs);
};
void initialize_dummy_ints(std::vector<int> &v, int size){
v.resize(size);
for (int n = 0; n < size; ++n)
v[n] = n + 1;
}
bool Vectors::save(const char * filename){
std::ofstream out(filename, std::ios::binary);
int a=A.size(), b=B.size(), c=C.size(), d=D.size(), e=E.size(), f=F.size();
out.write(reinterpret_cast<const char*>(&a), sizeof(a));
out.write(reinterpret_cast<const char*>(&b), sizeof(b));
out.write(reinterpret_cast<const char*>(&c), sizeof(c));
out.write(reinterpret_cast<const char*>(&d), sizeof(d));
out.write(reinterpret_cast<const char*>(&e), sizeof(e));
out.write(reinterpret_cast<const char*>(&f), sizeof(f));
out.write(reinterpret_cast<const char*>(&A[0]), sizeof(int)*A.size());
out.write(reinterpret_cast<const char*>(&B[0]), sizeof(int)*B.size());
out.write(reinterpret_cast<const char*>(&C[0]), sizeof(int)*C.size());
out.write(reinterpret_cast<const char*>(&D[0]), sizeof(int)*D.size());
out.write(reinterpret_cast<const char*>(&E[0]), sizeof(int)*E.size());
out.write(reinterpret_cast<const char*>(&F[0]), sizeof(int)*F.size());
// always check to see if the file opened, and if writes succeeded.
// I am being lazy here so I can focus on the actual question
return true;
}
bool Vectors::load(const char *filename){
std::ifstream in(filename, std::ios::binary);
int a, b, c, d, e, f;
in.read(reinterpret_cast<char*>(&a), sizeof(a));
in.read(reinterpret_cast<char*>(&b), sizeof(b));
in.read(reinterpret_cast<char*>(&c), sizeof(c));
in.read(reinterpret_cast<char*>(&d), sizeof(d));
in.read(reinterpret_cast<char*>(&e), sizeof(e));
in.read(reinterpret_cast<char*>(&f), sizeof(f));
A.resize(a); B.resize(b); C.resize(c); D.resize(d); E.resize(e); F.resize(f);
in.read(reinterpret_cast<char*>(&A[0]), sizeof(int)*A.size());
in.read(reinterpret_cast<char*>(&B[0]), sizeof(int)*B.size());
in.read(reinterpret_cast<char*>(&C[0]), sizeof(int)*C.size());
in.read(reinterpret_cast<char*>(&D[0]), sizeof(int)*D.size());
in.read(reinterpret_cast<char*>(&E[0]), sizeof(int)*E.size());
in.read(reinterpret_cast<char*>(&F[0]), sizeof(int)*F.size());
// always check to see if the file opened, and if writes succeeded.
// I am being lazy here so I can focus on the actual question
return true;
}
bool matches(const std::vector<int> &l, const std::vector<int> &r){
if (l.size() != r.size())
return false;
for (size_t x = 0; x < l.size(); ++x)
if (l[x] != r[x])
return false;
return true;
}
bool Vectors::operator==(const Vectors &rhs){
return matches(A, rhs.A) && matches(B, rhs.B) && matches(C, rhs.C) && matches(D, rhs.D) && matches(E, rhs.E) && matches(F, rhs.F);
}
int main()
{
// setup
Vectors starting_values;
initialize_dummy_ints(starting_values.A, 10);
initialize_dummy_ints(starting_values.B, 12);
initialize_dummy_ints(starting_values.C, 14);
initialize_dummy_ints(starting_values.D, 10);
initialize_dummy_ints(starting_values.E, 5);
initialize_dummy_ints(starting_values.F, 2);
// write to file
starting_values.save("data.bin");
// read back in to memory
Vectors loaded_values;
loaded_values.load("data.bin");
// compare
if (loaded_values == starting_values)
std::cout << "success";
else
std::cout << "failure";
return 0;
}
关于c++,如何一次将几个简单的 vector 写入二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31212680/