Инициализация большого вектора в C++ из другой программы
Изучаю C++.Есть процесс где содержится вектор с огромными данными, который имеет такую структуру:
std::vector<std::vector<std::vector<double>>>
Так вот, программы работают не одновременно, то есть нужно как сохранить в каком то виде вектор потом я запускаю следующею программу и та должна скопировать данные из первой программы, которая к тому моменту должна быть завершена. Пытался сериализовать но не выходит:
std::ofstream os ("list.dat", std::ios::binary);
size_t size1 = list1.size();
os.write((std::vector<std::vector<double>>)&size1, 3);
os.write((std::vector<std::vector<double>>)&list[0], size1 * sizeof(list1));
os.close();
next programm>>>
std::vector<std::vector<std::vector<double>>> list2;
std::ifstream is("list.dat", std::ios::binary);
int size2;
is.read((std::vector<std::vector<double>>)&size2, 3);
list2.resize(size2);
is.read((std::vector<std::vector<double>>)&list2[0], size2 * sizeof(???));
is.close();
Есть конечно вариант с обычной txt, но хотелось бы сделать по правильному
Ответы (1 шт):
Примерно так:
ostream& write(ostream& out, const vector<vector<double>>& d)
{
size_t sz = d.size();
out.write((char*)&sz,sizeof(sz));
for(const auto& v:d)
{
sz = v.size();
out.write((char*)&sz,sizeof(sz));
out.write((char*)v.data(),sz*sizeof(double));
}
return out;
}
istream& read(istream& is, vector<vector<double>>& d)
{
d.clear();
size_t sz;
is.read((char*)&sz,sizeof(sz));
d.resize(sz);
for(auto& v:d)
{
is.read((char*)&sz,sizeof(sz));
v.resize(sz);
is.read((char*)v.data(),sz*sizeof(double));
}
return is;
}
int main(int argc, const char * argv[])
{
vector<vector<double>> z = {{1,2,3},{9,8,7}}, t;
ofstream os ("list.dat", ios::binary);
write(os,z);
os.close();
ifstream is ("list.dat", ios::binary);
read(is,t);
is.close();
cout << (z == t) << endl;
for(auto x: z)
{
for(auto y: x) cout << y << " ";
cout << "\n";
}
cout << "\n\n";
for(auto x: t)
{
for(auto y: x) cout << y << " ";
cout << "\n";
}
cout << "\n\n";
}
Обработку ошибок при открытии/записи/чтении допишите сами. Для тройного вектора - то же самое, с дополнительным уровнем рекурсии...
Update
Можно через шаблоны и специализацию - еще интереснее, уровень вложенности обработается автоматически...
template<typename T>
ostream& write(ostream& out, const vector<T>& d)
{
size_t sz = d.size();
out.write((char*)&sz,sizeof(sz));
out.write((char*)d.data(),sz*sizeof(T));
return out;
}
template<typename T>
istream& read(istream& is, vector<T>& d)
{
d.clear();
size_t sz;
is.read((char*)&sz,sizeof(sz));
d.resize(sz);
is.read((char*)d.data(),sz*sizeof(T));
return is;
}
template<typename T>
ostream& write(ostream& out, const vector<vector<T>>& d)
{
size_t sz = d.size();
out.write((char*)&sz,sizeof(sz));
for(const auto& v:d)
{
write(out,v);
}
return out;
}
template<typename T>
istream& read(istream& is, vector<vector<T>>& d)
{
d.clear();
size_t sz;
is.read((char*)&sz,sizeof(sz));
d.resize(sz);
for(auto& v:d)
{
read(is,v);
}
return is;
}