无法在二进制文件中存储动态数组
Unable to store dynamic arrays in binary files
我需要能够在结构中存储数组,然后将结构另存为字节文件。问题是我要求数组是动态的。指针数组是不可能的,因为在保存时,它只会保存指针,而矢量将不起作用。这是我正在使用的当前设置的示例。
struct GenerationBase
{
//float value[]; // Will override data currently in ram
//float value[10]; // Dose not work as it needs to have a dynamic size
//float* value; // Will only save the pointer value
//std::vector<float> value; // Dose not work for some reason
};
template<typename T>
void write_to_file(std::ofstream& stream, T data)
{
stream.write(reinterpret_cast<const char*>(&data), sizeof(T));
}
int main()
{
const char* file = "file.txt";
GenerationBase write{};
std::ofstream stream_write(file, std::ios::binary);
write_to_file(stream_write, write);
stream_write.close();
}
注释中的所有注释都是正确的 - 您必须使用一些库进行序列化。 protobuf,boost::serialization是很好的二进制格式,JSON和XML是文本存储的不错选择。
这种方法存在更根本的问题,但是结构的字节组成取决于许多因素:编译器、字节序、32 位或 64 位架构。这意味着您不能简单地将C++数据结构的字节内容存储在文件中。
当使用具有动态大小的结构时,"大小将在运行时而不是编译时确定",则可以使用未指定大小的数组(如float value[]
(作为该结构的最后一个成员。但是请注意,您必须"手动"为结构分配适当大小的内存。C的情况如此,C++也是如此。不幸的是,使用运算符new
时手动定义大小相当棘手,因为new
使用类型来确定大小,而不是任何运行时值。所以你可能会使用malloc
和free
,这在C++中看起来有点错位。
更简单的解决方案是使用std::vector
,而不是写入结构内存的转储,而是写入向量的内容。
无论如何,对于您遵循的每种方法,您还必须将数组中的元素数量写入文件;否则 - 至少如果您将几个这样的结构顺序写入同一文件 - 您可能会丢失存储在文件中的(动态(数组实际有多少元素的信息。当然,读入过程必须考虑这个数字,并相应地创建/修改structs
。
请参阅以下代码,其中演示了 (1( 矢量方法和 (2( 具有可变大小方法的结构。希望它以某种方式有所帮助。
struct GenerationBase_UsingVector
{
std::vector<float> value;
void write(std::ofstream &w) const {
size_t num_elems = value.size();
w.write((const char*)&num_elems, sizeof(num_elems));
w.write((const char*)value.data(), num_elems*sizeof(float));
}
void read(std::ifstream &r) {
size_t num_elems;
r.read((char *)&num_elems, sizeof(num_elems));
float f;
while (num_elems--) {
r.read((char *)&f, sizeof(f));
value.push_back(f);
}
}
};
struct GenerationBase_PlainArray
{
size_t num_elems;
float value[];
static GenerationBase_PlainArray* create(size_t num_elems)
{
GenerationBase_PlainArray* result = (GenerationBase_PlainArray*)malloc(sizeof(GenerationBase_PlainArray) + num_elems*sizeof(float));
result->num_elems = num_elems;
return result;
}
static struct GenerationBase_PlainArray* newFromStream(std::ifstream &r) {
size_t num_elems;
r.read((char *)&num_elems, sizeof(num_elems));
GenerationBase_PlainArray* result = GenerationBase_PlainArray::create(num_elems);
r.read((char *)result->value, num_elems*sizeof(float));
return result;
}
void write(std::ofstream &w) const {
w.write((const char*)&num_elems, sizeof(num_elems));
w.write((const char*)value, num_elems*sizeof(float));
}
};
int main() {
GenerationBase_UsingVector gb_vector_forwrite;
gb_vector_forwrite.value.push_back(1.0);
gb_vector_forwrite.value.push_back(2.0);
gb_vector_forwrite.value.push_back(3.0);
gb_vector_forwrite.value.push_back(4.0);
gb_vector_forwrite.value.push_back(5.0);
gb_vector_forwrite.value.push_back(6.0);
std::ofstream write("test.bin", std::ios::binary);
gb_vector_forwrite.write(write);
write.close();
GenerationBase_UsingVector gb_vector_forread;
std::ifstream read("test.bin", std::ios::binary);
gb_vector_forread.read(read);
read.close();
for (auto f : gb_vector_forread.value) {
cout << f << endl;
}
GenerationBase_PlainArray* gb_array_forwrite = GenerationBase_PlainArray::create(6);
gb_array_forwrite->value[0] = 1.0;
gb_array_forwrite->value[1] = 2.0;
gb_array_forwrite->value[2] = 3.0;
gb_array_forwrite->value[3] = 4.0;
gb_array_forwrite->value[4] = 5.0;
gb_array_forwrite->value[5] = 6.0;
std::ofstream write2("test2.bin", std::ios::binary);
gb_array_forwrite->write(write2);
write2.close();
free(gb_array_forwrite);
std::ifstream read2("test2.bin", std::ios::binary);
GenerationBase_PlainArray *gb_array_forread = GenerationBase_PlainArray::newFromStream(read2);
read2.close();
for (int i=0; i<gb_array_forread->num_elems; i++) {
cout << gb_array_forread->value[i] << endl;
}
free(gb_array_forread);
}
相关文章:
- C++ 使用存储在动态数组中的文本文件中的数据查找模式
- C++ 将抽象类型的动态分配对象传递给函数并存储在向量中
- 存储指向动态数组元素的指针
- 具有对齐存储的动态内存分配
- 在字符串数组中动态创建和存储数据
- 如何在一个属性中动态存储基元类型
- 无法在二进制文件中存储动态数组
- 引发未经处理的异常:简单 C++ 程序中的读取访问冲突,动态增加数组长度以存储数字
- 在存储库中,筛选器函数返回动态向量或其他存储库
- 将指针或一系列指针存储在动态阵列中
- 如何从文件中读取并将内容存储在动态 2D 数组中并以网格格式显示
- 在类存储结构中使用动态分配的数组
- 存储值的动态数组
- 存储位置作为放大动态数组中的最后值
- 动态分配存储数据在堆中的随机位置中
- 存储矢量中的动态阵列
- 创建一个动态2D数组来存储类对象
- 如何在Qt中最好地存储动态创建的小部件的数据
- 存储动态创建对象的列表/向量的最佳方法是什么
- 我如何创建一个多层感知机以下DOD?或者如何存储动态分配的数组