Search code examples
c++filevectorstlfwrite

Writing vector of objects to file


How to write an object which contains multiple char pointers to a file and read back?

class Student {
        public:
                char* name;
                char* age;
                int size;

                Student(char* _name, char* _age) {
                        name = _name;
                        age = _age;
                        size = 0;
                        size = strlen(_name) + strlen(_age);
                }
};

I am having an vector array of Student objects ( vector<Student*> ). How to write this vector to a file and then read back ?

Can somebody please help on this? Can we do this without the help of boost::serialization ?


Solution

  • First of all prefer std::string over char*. You don't need the size then anymore. Also prefer initialization in constructors over assigning values in the constructor body:

    class Student {
        public:
            std::string name;
            std::string age;
    
            Student(const std::string& _name, const std::string& _age) : 
                name{_name}, age{_age}
            {};
    
            auto size() const -> size_t {
                return name.size() + age.size();
            };
    };
    

    Coming back to your question. Before you try to store a complex structure, you have to define the format. In this case I chose a simple CSV with semicolons as field separators and no quotes.

    void writeStudents(std::ostream& o, const std::vector<Student*>& students) {
        for(auto s: students) {
            o << s->name << ';' << s->age << '\n';
        }
    }
    void writeStudents(std::ostream&& o, const std::vector<Student*>& students) {
        writeStudents(o, students);
    }
    

    Now you can produce that csv with a `std::ofstream``:

    writeStudents(std::ofstream{"myFilename"}, students);
    

    To read it back, you'll have to parse the format you have defined before:

    auto readStudents(std::istream& i) -> std::vector<Student*> {
        auto students = std::vector<Student*>;
        auto line = std::string{};
    
        while( std::getline(i, line) ) {
            auto pos = line.find_first_of(';');
            students.push_back(new Student{std::string{line, 0, pos},
                                           std::string{line, pos+1}});
        }
    
        return students;
    }
    auto readStudents(std::istream&& i) -> std::vector<Student*> {
        return readStudents(i);
    }
    

    Now you can read your file with an std::ifstream:

    auto students = readStudents(std::ifstream{"myFilename"});
    

    Note: All code in this answer is untested. Beware of bugs, of course. I also left the error handling for you, because I did not want to pollute the answer with that noise.

    BTW.: How are you making sure, that the memory for your students is managed correctly? Consider to use std::unique_ptr<> or std::shared_ptr<> instead of raw pointers.