-1

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.

3
  • see if this does what you need: boost.org/doc/libs/1_75_0/libs/serialization/doc/index.html Commented Apr 10, 2021 at 15:28
  • Unfortunately, for this project, we are not allowed to use 3rd party libraries. Commented Apr 10, 2021 at 15:47
  • 1. Define some binary file format. Specify the byte order and how to serialize strings, for example. 2. Create functions to write each field into the file and read from the file. Commented Apr 10, 2021 at 15:53

1 Answer 1

1

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 :)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.