I am looking for an easy way to save and load this C++ object to and from a binary file.
#include <iostream>
#include <vector>
class User
{
private:
std::string _name;
int _age;
std::vector<std::string> _hobbies;
public:
std::string Name() { return _name; }
int Age() { return _age; }
std::vector<std::string> Hobbies() { return _hobbies; }
void Hobbies(std::string hobbieName)
{
_hobbies.push_back(hobbieName);
}
User(std::string name, int age)
{
_name = name;
_age = age;
}
};
int main()
{
User u1 = User("John", 48);
u1.Hobbies("Art");
u1.Hobbies("Lego");
u1.Hobbies("Blogging");
User u2 = User("Jane", 37);
u2.Hobbies("Walking");
u2.Hobbies("Chess");
u2.Hobbies("Card Games");
std::cout << u1.Name() << "'s Hobbies:\n";
for (std::string hobbie : u1.Hobbies())
{
std::cout << hobbie << "\n";
}
std::cout << u2.Name() << "'s Hobbies:\n";
for (std::string hobbie : u2.Hobbies())
{
std::cout << hobbie << "\n";
}
//Save 'u1' to file.
//Load 'u1' from file into a new 'User' object
}
I have looked at a number of StackOverflow answers for similar questions, but I am struggling to find a solution specifically regarding using the vector in my class. I would appreciate any suggestions that you might have.
Here is a very abstract idea of what you want, Write string size that helps to read string back for name, write age, again wite hobbies size that helps to read it again and finally write each string with it size. To read reverse the process,
#include <iostream>
#include <fstream>
#include <vector>
class User
{
private:
std::string _name;
int _age;
std::vector<std::string> _hobbies;
public:
std::string Name()
{
return _name;
}
int Age()
{
return _age;
}
std::vector<std::string> Hobbies()
{
return _hobbies;
}
void Hobbies(std::string hobbieName)
{
_hobbies.push_back(hobbieName);
}
User(std::string name, int age)
{
_name = name;
_age = age;
}
/**
* @brief saves to user binary file
*
* @param fout
*/
void save(std::ofstream &fout)
{
// write name
size_t nsiz = this->_name.size();
// write string size to read
fout.write((const char *)(&nsiz), sizeof(nsiz));
fout.write(&_name[0], nsiz);
// write age
fout.write((const char *)&_age, sizeof(int));
// write hobbies size
size_t hsiz = _hobbies.size();
fout.write((const char *)&hsiz, sizeof(size_t));
// write hobbies
for (auto &str : _hobbies)
{
size_t ssiz = str.size();
fout.write((const char *)(&ssiz), sizeof(ssiz));
fout.write(&str[0], str.size());
}
}
/**
* @brief loads from binary file
*
* @param fin
*/
void load(std::ifstream &fin)
{
// read name
size_t nsiz = 0;
fin.read((char*)&nsiz, sizeof(size_t));
this->_name.resize(nsiz);
fin.read(&_name[0], nsiz);
// read age
fin.read((char*)&_age, sizeof(int));
// read hobbies size
size_t hsiz = 0;
fin.read((char*)(&hsiz), sizeof(hsiz));
_hobbies.resize(hsiz);
for(size_t i = 0; i < hsiz; ++i)
{
size_t ssiz = 0;
fin.read((char*)&ssiz, sizeof(size_t));
_hobbies[i].resize(ssiz);
fin.read(&_hobbies[i][0], ssiz);
}
}
};
int main()
{
User u1 = User("John", 48);
u1.Hobbies("Art");
u1.Hobbies("Lego");
u1.Hobbies("Blogging");
std::ofstream fout("data.bin", std::ofstream::binary);
u1.save(fout);
fout.close();
User u2("", 0);
std::ifstream fin("data.bin", std::ifstream::binary);
u2.load(fin);
fin.close();
std::cout << u2.Name() << " with age " << u2.Age() << "'s Hobbies:\n";
for (std::string hobbie : u2.Hobbies())
{
std::cout << hobbie << "\n";
}
}
I hope that it helps, and make sure to do things what if string size is zero :)