Как из файла записать данные в структуру без разделителей C++?

Есть файл с данными:фио, номер телефона и т.д. Между ними стоит разделитель, в данном случае запятая.

Вот данные в файле:

Иванов Иван Иванович, 9773672365, 12.10.2012, 12.10.2014, 0, 0
Петров Иван Васильевич, 9734672311, 22.01.2008, 01.11.2011, 210, 200
Васильев Илья Васильевич, 9714679805, 05.09.2010, 01.12.2012, 0, 2000

Вот код:

Client client[10];

while (!file2.eof()) {
    for (int i = 0; i < 10; i++) {
        file2 >> client[i].firstname;
        file2 >> client[i].surname;
        file2 >> client[i].lastname;
        file2 >> client[i].phone_number;
        file2 >> client[i].start_date;
        file2 >> client[i].fin_date;
        file2 >> client[i].debt;
        file2 >> client[i].credit;
    }
}

В client[i].lastname записывается "Иванович," в phone_number "9773672365,".

Как из этого файла записать данные в структуру без запятых?


Ответы (1 шт):

Автор решения: KoVadim

Почти всегда, когда входные данные "пользовательские", нужно писать "парсер", который будет учитывать разные "особенности". Также неплохо делать разнообразные проверки.

По поводу while (!file2.eof()) - уже многократно обсуждалось, что это очень плохой паттерн.

#include <iostream>
#include <sstream>

// я эту структуру "восстановил"
struct Client {
    std::string firstname;
    std::string surname;
    std::string lastname;
    std::string  phone_number;
    std::string start_date;
    std::string fin_date;
    int debt;
    int credit;
};

int main() {
    // сохраним в специальном объекте, который умеет мимикрировать под файл
    std::istringstream file2(R"(Иванов Иван Иванович, 9773672365, 12.10.2012, 12.10.2014, 0, 0
Петров Иван Васильевич, 9734672311, 22.01.2008, 01.11.2011, 210, 200
Васильев Илья Васильевич, 9714679805, 05.09.2010, 01.12.2012, 0, 2000)");

    Client client[10];
    for (int i = 0; i < 10; i++) {
        std::string s;
        // читаем с новой строки во временную переменную
        if (!std::getline(file2, s, ' ')) { break;} // а если не вышло, то просто выходим
        client[i].firstname = s; // в случае успеха записываем в нужную переменную
        // будем считать, что если удалось прочитать фамилию, то все ок.
        // но по хорошему нужно проверять все чтение.
        std::getline(file2, client[i].surname, ' ');
        std::getline(file2, client[i].lastname, ',');
        std::getline(file2, client[i].phone_number, ',');
        std::getline(file2, client[i].start_date, ',');
        std::getline(file2, client[i].fin_date, ',');
        file2 >> client[i].debt;
        file2.ignore(10, ','); // проигнорием запятую. 10 - просто кол-во символов, на которые стоит посмотреть вперед. Скорее всего и 1 хватит
        file2 >> client[i].credit;
        file2.ignore(10, '\n'); // проигнорируем перевод строки
    }
    for (int i = 0; i < 3; i++) {
        std::cout << client[i].firstname << "|" << client[i].lastname <<  "credit " << client[i].credit << "\n";
    }
}
→ Ссылка