Sortowanie według imion i nazwisk (listа, obiekty klasy)

0
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <list>

using namespace std;


class Persona
{
    string imie, nazwisko;

public:

    Persona(string i, string n) : imie(i), nazwisko(n)
    {}

    void wypisz()
    {
        cout << imie << " " << nazwisko << " " << endl;
    }

    string GetKey1()
    {
        return nazwisko;
    }

    string GetKey2()
    {
        return imie;
    }
};


template<typename T>
void Printlist(list<T>& lst)
{
    for (auto i = lst.begin(); i != lst.end(); i++)
    {
        (*i).wypisz();
    }
}


int main()
{

    list<Persona> word;
    string im, nazw;
    ifstream plik;

    plik.open("persona.txt", ios::in);

    if (plik.good() == false)
    {
        cout << "Plik nie istnieje" << endl;
        exit(0);
    }

    do
    {
        getline(plik, im, ' ');
        getline(plik, nazw);
        word.push_back(Persona(im, nazw));

    } while (word.size() != 20);

   
    //plik.close();

    cout << "Lista: " << endl;
    Printlist(word);
    cout << "\n\n";

}

Dzień dobry. Mam taki problem, że musze posortować dane w pliku według imion i nazwisk.

Plik ma taką informację: (2 słowa w jednej linijce, jest to obowiązkowo)
Mikolaj Plank
Elzbieta Felak
Andrzej Felak
Marek Kostkowski
Teodozja Lorant
Antoni Lorant
Klara Onyx
Lucjan Larbinski
...

Problem polega na tym, że nie wiem, jak musze to posortować, sortowanie musze być wykonane za pomocą wszystkich Getów, i metody wypisz. Czego brakuje w moim kodzie? Potrzebuję tylko podpowiedzi, ponieważ sam chcę to zrozumieć

2

Musisz zdefiniować własną metodę sortowania obiektów Persona. Najlepiej jest to zrobić przy użyciu wyrażenia Lambdy
W tym przypadku sortujemy po nazwisku, jeżeli nazwiska są takie same, to wtedy sortowanie odbywa się po imionach.

 auto fn = []( const Persona& p1 , const Persona& p2 )
               {
                   return (p1.GetKey1()!=p2.GetKey1())?p1.GetKey1()<p2.GetKey1():p1.GetKey2()<p2.GetKey2();
               };
 word.sort(fn);

Pamiętaj jeszcze aby dodać słowo kluczowe const do metod GetKey, aby można je było użyć poprawnie wewnątrz wyrażenia fn.

 string GetKey1() const
 {
     return nazwisko;
 }

 string GetKey2() const
 {
     return imie;
 }
2
  1. zamiast metody wypisz zastosuj friend operator<<(), na razie twoja klasa jest niepotrzebnie powiązana z std::cout
  2. getNazwisko, getImie zamiast GetKey1, etc.
  3. zaimplementuj operator<(), wtedy lista.sort() będzie w stanie posortować obiekty. Drugi sposób to lista.sort(komparator) z komparatorem w postaci funkcji albo lambdy.
  4. list<Persona> word - zamiast word daj persons, liczba mnoga
  5. while (word.size() != 20) magiczne liczby to zło. Bardziej pasowało by while (plik), w przypadku niepowodzenia getline, strumień zwróci false i można to wykorzystać
2
  1. prostsza byłaby pętla "for range", dodatkowo argument const, wtedy funkcja jest w stanie przyjąć stałą listę.
template <typename T>
void Printlist(const list<T>& lst) {
    for (const auto& i : lst) {
        cout << i << endl;
    }
}
...
    const list<Persona> placeholders{{"Jan", "Kowalski"}, {"Katarzyna", "Kowalska"}};
    Printlist(placeholders);
  1. stosując standard c++17 można otwierać pliki w ten sposób:
    list<Persona> personas;

    if (ifstream plik("persona.txt", ios::in); plik) {
        //...
    } else {
        cout << "Plik nie istnieje" << endl;
        exit(1);
    }

po zakończeniu sekcji warunkowej plik zostanie zamknięty, a zmienna "plik" nie będzie widoczna w dalszej części programu
8. Jak coś się nie powiedzie to nie zwracamy zero exit(0), tylko inną wartość. Zero oznacza prawdę. Może się to przydać gdy wołamy nasz program ze skryptu, lub np. tak:

$ ./naszprogram && echo "Program sie powiodl"
  1. porównanie z false lub true można uprościć:
if (plik.good() == false) {}
if (!plik.good()) {}
  1. czasami stosowanie zbyt krótkich nazw zmiennych może utrudnić w przyszłości szybką analizę programu:
string im, nazw;
string imie, nazwisko;

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