Имеется структура:
struct str
{
int a;
bool b;
};
Также есть вторая:
struct str2
{
int c;
int d[5];
std::vector<str>vec;
};
На её основе строится вектор:
std::vector<str2>vec_2;
Нужно сохранить этот вектор в файл, а также считать из файла обратно в память.
То, что вы хотите, называется сериализациея/десериализация. Существует довольно много решений на этот счет, например, boost::serialization.
Одним из простых кросплатформенных способов сериализации является использование QDataStream и перегрузка operator << и operator >> для пользовательских типов. Любой массив записывается в виде
stream << std::int64_t{array.size};
for(auto&& x: array)
stream << x;
и считывается в обратном порядке, для контейнеров из Qt уже предусмотрены перегрузки.
Пример перегрузок:
QDataStream& operator << (QDataStream& stream, const str& rha){
return stream
<< int64_t{rha.a}
<< rha.b;
}
QDataStream& operator >> (QDataStream& stream, const str& rha){
int64_t a; // Нужен платформонезависимый тип
stream >> a;
rha.a = a;
stream >> rha.b;
return stream;
}
str str_1 {123, false};
str str_2;
{
File file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << str1;
}
{
File file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
in >> str2;
}
Для обработки ошибок можно бросать исключения (без этого есть шанс заполнить все структуры нулями и долго искать ошибку).
Строки таким образом сериализовывать нельзя, нужно преобразовывать их в нормальный массив, например, в utf8, и уже его записывать, т.к. чтение и запись строк в потоки обычно не симметричны.
То же самое можно делать и со стандартными потоками, но там есть проблема с кросплатформенностью.
Для начала нужно определить методы чтения/записи вашей структуры. Для этой цели хорошо подходят операторы << и >>.
std::ostream& operator<<(std::ostream &os, const str &value){
os << value.a << value.b;
return os;
}
std::istream& operator>>(std::istream &is, str &value){
is >> value.a >> value.b;
return is;
}
Теперь писать структуру в файл можно так:
std::fstream ofs("file");
str s;
ofs << s;
а читать так:
std::fstream ifs("file");
str s;
ifs >> s;
Чтобы записать вектор структур в файл, можно сделать так:
std::fstream ofs("file");
std::vector<str> v = {...};
std::copy(v.begin(), v.end(), std::ostream_iterator<str>(ofs));
Чтобы прочитать вектор структур, можно сделать так:
std::fstream ifs("file");
std::vector<str> v;
std::copy(std::istream_iterator<str>(ifs), std::istream_iterator<str>(), std::back_inserter(v));
Это была инструкция для str. Вам нужно выполнить аналогичные действия и для str2.
Продвижение своими сайтами как стратегия роста и независимости