Iteratory i shared pointery.

0

Klasa Patient posiada pola:

int id;
char sex;
int id_father;
int id_mother;

Posiadam vector shared pointerów na obiekty Klasy Patient.

std::vector < std::shared_ptr<Patient>> patients;

oraz iterator na vector shared pointerów na obiekty Klasy Patient.

std::vector <std::shared_ptr <Patient>>::iterator iterator;

Z pliku szczytuję dane o pacjentach i tworzę obiekty.

while (!file.eof())
    {
        patients.push_back(std::shared_ptr <Patient>(new Patient));

        iterator = patients.end() - 1;

        line.clear();

        getline(file, line, '|');
        if (line.empty()) break;
        (*iterator)->set_id(atoi(line.c_str()));

        getline(file, line, '|');
        (*iterator)->set_sex(line);

        line.clear();
        getline(file, line, '|');
        if (line.empty())
        {
            (*iterator)->set_id_father(NULL);
            continue;
        }
        else
        {
            (*iterator)->set_id_father(atoi(line.c_str()));
        }

        line.clear();
        getline(file, line);
        if (line.empty())
        {
            (*iterator)->set_id_mother(NULL);
            continue;
        }
        else
        {
            (*iterator)->set_id_mother(atoi(line.c_str()));
        }

    }
Dane:
1|M|2|1 // odpowienio id, sex, id_father, id_mother
2|M|2|1
3|M|2|1
4|K|2|1
5|M|2|1

W mainie wypisuje dane:

for (iterator = patients.begin();  iterator != patients.end()-1; iterator++)
{
    std::cout << (*iterator)->get_id()<<std::endl; // 1,2,3,4,5
}

Wszystko się zgadza do momentu gdy nie usunę np. id_father lub id_mother z jednego pacjenta, wówczas w outpucie brakuje osoby o jeden niżej.

przykład:

Dane:
1|M|2|1 // odpowienio id, sex, id_father, id_mother
2|M
3|M|2|1
4|K|2|1
5|M|2|1

output:
1
2
4
5

1
  1. getline, jak podasz inny delimiter ignoruje znak nowej linii, więc Twoje sprawdzanie czy udało się wczytać jest zbędne. Ponadto:
  2. Nie używaj shared_ptr nadaremno, to powinien być ostatni resort, a nie pierwszy
  3. Jak już używasz shared_ptr to używaj make_shared, chyba że wiesz że nie powinieneś (prawie nigdy)
  4. vector::back() zamiast iteratora na end()-1
  5. for(auto const& el : patients) zamiast for (iterator = patients.begin(); iterator != patients.end()-1; iterator++). Zakładam, że wypisywanie bez ostatniego elementu to błąd

Ostatecznie, chciałbyś zapewne coś takiego:

vector<Patient> patients;
// ...
string line;
while(getline(file, line))
{
    string elem;
    stringstream linestream{line};
    Patient p;

    if(!getline(linestream, elem, '|'))
        continue;
    p.set_id(stoi(elem));

    if(!getline(linestream, elem, '|'))
        continue;
    p.set_sex(elem);

    if(!getline(linestream, elem, '|'))
        continue;
    p.set_id_father(stoi(elem));

    if(!getline(linestream, elem, '|'))
        continue;
    p.set_id_mother(stoi(elem));

    patients.push_back(move(p));
}

Wielokrotne sprawdzanie czy udało się wczytać można też opakować w pętlę ale chciałem zostawić blisko oryginalnego kodu. Jeśli chcesz dodawać osoby, przy których parsowaniu pojawił się problem, musisz przesunąć push_back na górę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0