二进制读/写任意 C++ 中的 std::vector<std::vector<int> >

binary read/write arbitrary std::vector<std::vector<int> > in c++

本文关键字:vector gt lt std int 任意 中的 C++ 二进制      更新时间:2023-10-16

Hi,我想在一个文件中存储二进制std::vector<std::vector<int> >对象MIX。

out.write((char*)&MATRIX, sizeof(MATRIX));

问题是,只有列维度是固定的。行维度发生更改。如果我从二进制文件中读取对象,只知道大小是不够的,不是吗?因此,用初始化例如第二个矩阵

std::vector<std::vector<int> > MATRIX2;
for ( int i=0;i<column_dim;i++ ) MATRIX2.push_back ( vector<int> ( 0 ) );
ifstream in(cstr, ios::in | ios::binary);

并用读取对象数据

ifstream in(cstr, ios::in | ios::binary);    
in.read((char*)& MATRIX2, fSize);

毫无意义,因为编译器对保存的数据的结构一无所知。我的问题:有没有比把矩阵结构(关于行维度的所有信息)保存在第二个文件中,读取它并创建一个具有适当结构的MIX2更好的方法来解决这个问题,然后用填充

ifstream in(cstr, ios::in | ios::binary);    
in.read((char*)&nn_H_test, fSize);

我将给您一个关于如何使用boost实现这一点的简短示例。

#include <iostream>
#include <fstream>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
std::vector<std::vector<int > > g_matrix;
int main(int argc, char* argv[])
{
    // fill the vector
    std::ofstream ofs("c:\dump");
    boost::archive::text_oarchive to(ofs);
    to << g_matrix;
    g_matrix.clear();
    std::ifstream ifs("c:\dump");
    boost::archive::text_iarchive infs(ifs);
    infs >> g_matrix;
    // check your vector. It should be the same
}

如果您需要它更易于阅读,您也可以尝试boost中的xml
一如既往,不要重新发明轮子。

ios::binary几乎肯定不会有你认为的结果——它只会影响行尾翻译。

其次,如果你想在阅读时恢复结构,你将无法避免存储内部向量的单个长度。将一个原始的std::矢量从流中直接恢复为一个新的std::矢量,就像您现在尝试的那样,永远不会奏效。

然而,结构化恢复并不困难,只需存储每个内部向量的值的数量,然后存储所有值。然后,您的读取例程可以安全地读取第一个值,然后读取N个下一个值,并假设之后的第一个值是下一行的值数。

对于非常简单的事情,为什么不在指定行-列大小的矩阵输出之前放置一个头值呢?琐碎的例子:

4,2 //#rows, #columns
0 1
2 0
2 3
4 5

现在,当你读入矩阵时,先读入标题信息,然后读入矩阵数据。

如果您希望矩阵是可序列化的,那么您应该查看矩阵结构的序列化范例。有关序列化的更多信息,请参阅C++常见问题解答。