C ++ читает строку к классу вектора - PullRequest
0 голосов
/ 21 октября 2018

У меня есть следующий класс c ++ под названием «Контакт»:

class Contact
{
private:
    std::string contactName;
    double subscriptionPrice;
    int minutesIncluded;

public:
    Contact(const std::string &contactName, double subscriptionPrice,
            int minutesIncluded) : contactName(contactName), subscriptionPrice(subscriptionPrice), minutesIncluded(minutesIncluded)) {}
    Contact() {

    }

    ...gettetrs and setters
}

У меня есть текстовый файл с одним или несколькими контактами в формате:

asd,1.00000,1

В основном методе у меня есть метод, которыйДобавьте правильно вектор контактов в этом текстовом файле.Проблема в том, когда я пытаюсь читать с него.Моя цель - преобразовать текстовый файл в вектор контактов.Метод, который я использую, следующий:

void phonebook_load(vector<Contact> &contacts)
{
    string line;
    ifstream phonebook_file;
    vector<std::string> lines;
    phonebook_file.open(phonebook_filename);
    if(!phonebook_file.is_open())
        cout << "Phonebook file could not be openned !!!" << endl;
    else
    {
        while (phonebook_file.good())
        {
            for (string line; getline(phonebook_file, line, ','); )
                lines.push_back(line);
        }
        phonebook_file.close();
    }
}

У меня есть два варианта:

  1. Читать строку за строкой (которую я не могу разделить на ",")
  2. Разделитьс помощью ",", которые печатают каждое свойство контакта в новой строке, и я не вижу, как это будет обрабатываться оттуда.

Что я должен изменить в своем методе, чтобы прочитать строку файлаи правильно преобразовать его в vector<Contact>

1 Ответ

0 голосов
/ 21 октября 2018

Укажите операторы извлечения и вставки потока для вашего типа:

#include <string>
#include <vector>
#include <iterator>
#include <fstream>
#include <iostream>


class Contact
{
private:
    std::string contactName;
    double subscriptionPrice;
    int minutesIncluded;

public:
    Contact() {}
    Contact(const std::string &contactName, double subscriptionPrice, int minutesIncluded)
    : contactName       { contactName },
      subscriptionPrice { subscriptionPrice },
      minutesIncluded   { minutesIncluded }
    {}

    // declare the stream extraction and stream insertion operators as firends
    // of your class to give them direct access to members without the need for
    // getter and setter functions.
    friend std::istream& operator>>(std::istream &is, Contact &contact);
    friend std::ostream& operator<<(std::ostream &os, Contact const &contact);
};

std::istream& operator>>(std::istream &is, Contact &contact)
{
    std::string contact_name;
    if (!std::getline(is, contact_name, ','))  // use getline with a delimiter
        return is;                             // to allow whitespace in names
                                               // which >> doesn't
    char seperator;
    double subscription_price;
    int minutes_included;
    if (!(is >> subscription_price >> seperator >> minutes_included) || seperator != ',') {     
        is.setstate(std::ios::failbit);
        return is;
    }

    contact = Contact{ contact_name, subscription_price, minutes_included };
    return is;
}

std::ostream& operator<<(std::ostream &os, Contact const &contact)
{
    os << contact.contactName << ", " << std::fixed << contact.subscriptionPrice
       << ", " << contact.minutesIncluded;
    return os;
}

int main()
{
    std::ifstream is{ "test.txt" };
    std::vector<Contact> contacts{ std::istream_iterator<Contact>{ is },
                                   std::istream_iterator<Contact>{} };

    for (auto const &c : contacts)
        std::cout << c << '\n';
}
...