2015-12-09 3 views
0

Как написать объект, который содержит несколько указателей на символ в файле и прочитать обратно?Написание вектора объектов в файл

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); 
       } 
}; 

Я имею вектор массив объектов Student (vector<Student*>). Как записать этот вектор в файл и затем прочитать его?

Может ли кто-нибудь помочь в этом? Можем ли мы сделать это без помощи boost::serialization?

+0

Вы можете, конечно, реализовать сериализацию самостоятельно. 'boost :: serialization' не производится из волшебной пыли pixie; это просто код, написанный людьми. – molbdnilo

+0

Пока ваш класс Student является POD, вы можете перебирать вектор и записывать студенческую структуру в файл как двоичный поток и продолжать добавлять его в файл. Во время чтения вы можете прочитать sizeof (Student) из файла, передать его в структуру Student до EOF. – Arunmu

+1

@Arunmu Не очень хорошая идея. Как вы можете видеть, в нем есть указатели. – molbdnilo

ответ

1

Прежде всего предпочитают std::string свыше char*. Вам больше не нужен размер. Также предпочитайте инициализацию конструкторов над назначением значений в корпусе конструктора:

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(); 
     }; 
}; 

Возвращаясь к вашему вопросу. Прежде чем пытаться сохранить сложную структуру, вы должны определить формат. В этом случае я выбрал простой CSV с точкой с запятой как разделители полей и без кавычек.

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); 
} 

Теперь вы можете производить этот файл CSV с `станд :: ofstream``:

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

Чтобы прочитать его обратно, вам придется разобрать формат, который вы определили раньше:

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); 
} 

Теперь вы можете прочитать файл с std::ifstream:

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

Примечание: весь код в этом ответе не проверен. Остерегайтесь ошибок, конечно. Я также оставил для вас обработку ошибок, потому что я не хотел загрязнять ответ этим шумом.

ОТВЕТ: Как вы убедитесь, что память для ваших учеников управляется правильно? Попробуйте использовать std::unique_ptr<> или std::shared_ptr<> вместо необработанных указателей.

+0

Вы должны взять временную ссылку const, она не будет компилироваться иначе. – Arunmu

+0

@Arunmu хороший catch. В этом случае потоки не могут быть постоянными. Я изменил свой anser на переменные для потоков вместо временных. – cdonat

+0

слишком плохо ostream не может быть перемещен – Arunmu

Смежные вопросы