2011-05-27 85 views
2

您好, 我想存储二进制一个std::vector<std::vector<int> >对象MATRIX在文件中。二进制读/写任意的std ::矢量<性病::矢量<int>>在C++

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); 

是没有意义的,因为编译器不具有关于所保存的数据的结构的线索。 我的问题: 解决这个问题比第二个文件中保存矩阵结构(关于行尺寸的所有信息)有什么更好的解决方法,读取它并创建一个MATRIX2和适当的结构,然后用

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

+2

是给定的文件格式?如果不是,也许你想看看http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/index.html。这应该会让你很容易存储和加载int的矩阵。 – mkaes 2011-05-27 12:44:45

+0

扩展我在http://stackoverflow.com/questions/3438132/serialise-and-deserialise-vector-in-binary/3438541#3438541中建议的协议,在每个存储矩阵前添加一个size_t来指定第一维。 – bobah 2011-05-27 12:46:56

+3

哎哟,你是否试图在文件上做一个原始的'std :: vector'转储?这将*永远不会*工作,读回来你会得到一个完全混乱的状态的对象(唯一正确的事情可能是矢量大小,但指向元素的内部指针将是无效的)。你需要正确的序列化。 – 2011-05-27 12:52:35

回答

3

我会给你一个关于如何使用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。
一如既往不要重新发明轮子。

+1

......除非是为了学习的目的! – fouronnes 2011-05-27 13:25:43

0

对于非常简单的事情,为什么不只是在指定行列大小的矩阵输出之前放置标题值?简单的例子:

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

现在,当你在矩阵中读取数据时,首先读入数据头信息,然后读入矩阵数据。

如果你想矩阵是可序列化的,你应该看看矩阵结构的序列化范例。详细了解C++ FAQ中的序列化。

+0

谢谢,是的,这也是我想到的第一件事,但它有一个缺点:我的一些算法已经使用这个矩阵,我不得不重写它们 - 不幸的是,这会导致更多的工作,添加一个额外的文件。 – 2011-05-27 12:56:46

+0

如果这是一个问题,那么序列化可能是您的解决方案。这样它就全部包含在矩阵中。 – nathan 2011-05-27 13:16:50

2

ios :: binary是almost certainly NOT going to have the result you think it will have - 它只影响行结束翻译。其次,如果你想在阅读时恢复结构,你不会逃避必须存储内部向量的个别长度。将一个原始的std :: vector从一个流直接恢复到一个新的std :: vector中,就像你现在要做的一样,不会有效。

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

+0

感谢您的评论。对你的第一个评论:你会建议什么? – 2011-05-27 13:08:13

+0

如果要将矢量存储为真正的“二进制”数据(例如,在磁盘上使用4个字节来存储4个字节的整数),则应考虑使用流读取和写入来编写自定义二进制文件流。 – 2011-05-27 13:35:41

相关问题