Запись обьекта с STL string, list, vector в бинарный файл
пытаюсь записать в бинарный файл обьект 'студент', кажется что-то не то с записью контейнеров, вот код, не знаю что еще добавить, исправляю уже час, всё никак.
class StudentA {
string surname;
string name;
int age;
string vuz;
vector<int> marks;
list<string> subjects;
//...
}
void StudentA::write_to_file(ofstream& os)
{
size_t sz = surname.length() + 1;
os.write((char*)&sz, sizeof(sz));
os.write((char*)surname.c_str(), sz);
sz = name.length() + 1;
os.write((char*)&sz, sizeof(sz));
os.write((char*)name.c_str(), sz);
os.write((char*)&age, sizeof(age));
sz = vuz.length() + 1;
os.write((char*)&sz, sizeof(sz));
os.write((char*)vuz.c_str(), sz);
sz = sizeof(marks);
os.write(reinterpret_cast<const char*>(&sz), sizeof(sz));
os.write(reinterpret_cast<const char*>(&marks[0]), sz * sizeof(marks[0]));
//............................... //CONTINUE
sz = sizeof(subjects);
os.write((char*)&sz, sizeof(sz));
for (auto val : subjects)
{
os.write((char*)val.c_str(), sizeof(val));
}
//CONTINUE
}
void StudentA::read_from_file(ifstream& in)
{
size_t sz;
in.read((char*)&sz, sizeof(sz));
char* buf = new char[sz];
in.read(buf, sz);
surname = buf;
delete[]buf;
in.read((char*)&sz, sizeof(sz));
buf = new char[sz];
in.read(buf, sz);
name = buf;
delete[]buf;
in.read((char*)&age, sizeof(age));
in.read((char*)&sz, sizeof(sz));
buf = new char[sz];
in.read(buf, sz);
vuz = buf;
delete[]buf;
const size_t count = sizeof(*this) / sizeof(int);
vector<int> vec(count);
in.read(reinterpret_cast<char*>(&vec[0]), count * sizeof(int));
//............................... //CONTINUE
in.read((char*)&sz, sizeof(sz));
for (; sz > 0; sz -= sizeof(string))
{
buf = new char[sizeof(string)];
in.read(buf, sz);
subjects.push_back(buf);
delete[]buf;
}
//CONTINUE
}
Ответы (1 шт):
Автор решения: gbg
→ Ссылка
Правило примерно такое - не сбрасывать в файл объекты, которые прямо или косвенно содержат ссылки или указатели.
Код ниже:
in.read((char*)&sz, sizeof(sz));
for (; sz > 0; sz -= sizeof(string))
{
buf = new char[sizeof(string)];
in.read(buf, sz);
subjects.push_back(buf);
delete[]buf;
}
Не работает именно по этой причине. Так что делайте как в коде выше - записывайте длину строки, а потом ее содержимое.
Еще одна проблема - то как вы читаете строки из файла. Нерационально выделять временный буфер - можно сразу задавать вашим строкам нужный размер:
size_t sz;
in.read((char*)&sz, sizeof(sz));
surname.resize(sz);
in.read(surname.data(), sz);