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