Krishna M
Krishna M

Reputation: 1195

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 ?

Upvotes: 1

Views: 3290

Answers (1)

cdonat
cdonat

Reputation: 2822

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.

Upvotes: 2

Related Questions