Reputation: 912
Hi,
I would like to store binary a std::vector<std::vector<int> >
object MATRIX in a file.
out.write((char*)&MATRIX, sizeof(MATRIX));
The problem is, that only the column dimension is fixed. The row dimension changes. If I read the object out of the binary file, it's not enough to know only the size, isn't it? So, initializing e.g. a second matrix with
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);
and reading the object data with
ifstream in(cstr, ios::in | ios::binary);
in.read((char*)& MATRIX2, fSize);
makes no sense, because the compiler has no clue about the structure of the saved data. My question: Is there any better way of solving this problem than saving the matrix structure (all info about the row dimensions) in a second file, reading it and creating a MATRIX2 with the appropriate structure which is then filled by using
ifstream in(cstr, ios::in | ios::binary);
in.read((char*)&nn_H_test, fSize);
?
Upvotes: 2
Views: 1850
Reputation: 14119
I will give you a short example on how to do this with 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
}
If you need it to be more human readable you can also try the xml out from boost.
As always don't reinvent the wheel.
Upvotes: 3
Reputation: 10988
ios::binary is almost certainly NOT going to have the result you think it will have - it only affects line ending translation.
Secondly, you are not going to escape having to store the individual lengths of the inner vectors if you want to restore the structure upon reading. Restoring a raw std::vector from a stream directly into a new std::vector like you are trying to now is not going to work, ever.
Structured restoring however need not be difficult, just store the number of values, and then all the values, for each inner vector. Your read routine can then safely read the first value, then read N next values, and assume the first value after that is the number of values of the next row.
Upvotes: 2
Reputation: 5733
For something extremely simple why not just place a header value before your matrix output that specifies row column size? Trivial example:
4,2 //#rows, #columns
0 1
2 0
2 3
4 5
Now when you read in the matrix, read in the header information and then the matrix data.
If you want the matrix to be serializable, you should look at a serialization paradigm for your matrix structure. Read more about serialization in the C++ FAQ.
Upvotes: 0