Сериализация класса C ++ - PullRequest
       10

Сериализация класса C ++

2 голосов
/ 15 апреля 2009

Я совсем недавно узнал о ключевом слове друзей классов C ++ и его использовании в сериализации, и теперь мне нужна помощь, чтобы заставить его работать.

У меня нет проблем с сериализацией моего класса в файл, он работает отлично, однако мне трудно пытаться прочитать этот файл в векторный контейнер. Я уверен, что мне нужен цикл в моем коде, который читает строку за строкой, но так как класс имеет разные типы, я думаю, я не могу использовать std :: getline (), а также, возможно, этот подход не будет использовать метод istream реализованы? Пример выходного файла будет:

Person 1
2009
1

Person 2
2001
0

Мой код:

class SalesPeople {
    friend ostream &operator<<(ostream &stream, SalesPeople salesppl);
    friend istream &operator>>(istream &stream, SalesPeople &salesppl);

    private:
        string fullname;
        int employeeID;
        int startYear;
        bool status;
};

ostream &operator<<(ostream &stream, SalesPeople salesppl)
{
    stream << salesppl.fullname << endl;
    stream << salesppl.startYear << endl;
    stream << salesppl.status << endl;
    stream << endl;
    return stream;
}

istream &operator>>(istream &stream, SalesPeople &salesppl)
{
    stream >> salesppl.fullname;
    stream >> salesppl.startYear;
    stream >> salesppl.status;
    // not sure how to read that empty extra line here ?
    return stream;
}

// need some help here trying to read the file into a vector<SalesPeople>
SalesPeople employee;
vector<SalesPeople> employees;

ifstream read("employees.dat", ios::in);
if (!read) {
   cerr << "Unable to open input file.\n";
   return 1;
}

// i am pretty sure i need a loop here and should go line by line 
// to read all the records, however the class has different
// types and im not sure how to use the istream method here.

read >> employee;
employees.push_back(employee);

Кстати, я знаю, что у библиотеки Boost отличный класс сериализации, однако сейчас я пытаюсь узнать, как сериализация будет работать с использованием библиотеки STL. Заранее большое спасибо за любую помощь, которую вы можете оказать мне, и за то, что помогли мне встать на правильный путь!

Ответы [ 2 ]

2 голосов
/ 15 апреля 2009

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

  • Для чтения SalesPeople в петля, я бы порекомендовал вам взять посмотрите на этот FAQ . Имеет Пример почти точно, что вы необходимость. FAQ 15.4 тоже поможет Вы, я верю.

  • На ваш вопрос о том, как справиться лишняя пустая строка при чтении из файла, проверьте это ссылка . Вы можете очень просто извлечь пробел таким образом.

  • Как предложил jfclavette, я бы рекомендую заглянуть в std :: getline для чтения в Полное имя SalesPerson, так как вы нужно все на этой линии в одно строка.

У меня есть к вам один вопрос: а как насчет employeeID? Я заметил, что это игнорируется в вашем примере кода. Это специально?

А теперь, если вам все еще нужна помощь, вы можете проверить код, который я написал, чтобы заставить его работать:

istream &operator>>(istream &stream, SalesPeople &salesppl)
{
    //stream >> salesppl.fullname;
    getline(stream, salesppl.fullname);
    stream >> salesppl.startYear;
    stream >> salesppl.status;
    // not sure how to read that empty extra line here ?
    stream >> ws;
    return stream;
}

while(read >> employee)
{
    // cout << employee; // to verify the input, uncomment this line
    employees.push_back(employee);
}

Также, как предположил jfclavette, может быть неплохо добавить некоторую проверку входных данных (проверьте состояние потока после чтения из него и убедитесь, что оно все еще исправно). Хотя я бы рекомендовал использовать цикл while () по причинам, указанным в FAQ 15.5 .

1 голос
/ 15 апреля 2009

Не уверен, в чем ваша проблема. Что именно вы не понимаете? В том, что ваши имена состоят из нескольких токенов? Нет волшебного способа сделать это, вы можете получить имя через getline (). В качестве альтернативы, вы можете указать количество токенов при сериализации и прочитать соответствующее количество токенов. т. е. ваш файл может выглядеть следующим образом.

2 человека 1

Я предположил, что Персона была первым именем, а 1 - фамилией здесь. Вы также можете применить понятие, что есть одно имя и одна фамилия, и просто читать каждое из них отдельно.

Как правило, вы будете выполнять цикл while (! Ifstream.eof ()) и читать Конечно, вы всегда должны проверять вводимые данные.

Кроме того, почему вы добавляете дополнительный endl между каждой записью? Сериализованные данные не должны быть красивыми. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...