C++ Kurs

Wenn fertig, bitte Fenster schließen

Lösung zur Lektion "Standard Container"


// Loesung zu Container

#include <iostream>
#include <string>
#include <map>
#include <iterator>

using std::cout;
using std::endl;
using std::string;

// Adressbuch Klasse
// Lässt keine doppelten Einträge zu
class AddressBook
{
    // Adressdaten, ohne Name
    // ACHTUNG! Falls Adressdaten auch Zeiger oder weiter Objekte
    // enthalten, so muss der copy-ctor, der = Operator und
    // der dtor noch definiert werden. Die string-Objekte sind
    // direkt kopierbar (per Zuweisung)
    struct Entry
    {
        string phone;   // Telefon-Nummer
        string email;   // EMail
        // ctor
        Entry(const string& phone_, const string& email_): phone(phone_), email(email_)
        {}
    };
    // Map für Adressbuch-Einträge, Schlüssel ist Name
    // Die Nutzdaten sind in der Struktur Entry zusammengefasst
    typedef std::map<string,Entry> bookmap;
    bookmap theBook;
  public:
    // ctor
    AddressBook()
    {}
    // dtor
    ~AddressBook()
    {}
    // Neue Adresse aufnehmen
    void Insert(const string& name, const string& phone, const string& email);
    // Gibt einzelne Adresse aus
    void PrintAddress(const string& name);
    // Ändert Adressbuch-Eintrag
    bool Update(const string& name, const string& phone, const string& email);
    // Adresse entfernen
    void Remove(const string& name);
    // Liefert Anzahl der Adressbuch-Einträge
    size_t size()
    {
        return theBook.size();
    }
    // Gibt gesamtes Adressbuch aus
    friend std::ostream& operator << (std::ostream& os, AddressBook& abook);
};
// Ausgabe einer Adresse
void AddressBook::PrintAddress(const string& name)
{
    // Suche nach Namen
    bookmap::iterator iter = theBook.find(name);
    // Falls Name nicht im Adressbuch
    if (iter == theBook.end())
        cout << "Kein entsprechender Eintrag gefunden!\n";
    else
    {
        // Sonst Adressdaten ausgeben, Iterator zeigt auf gefunden Eintrag
        cout << "Name: " << iter->first << '\n'
             << "Tel : " << iter->second.phone
             << ", Email: " << iter->second.email << endl;
    }
}
// Neuen Eintrag ins Adressbuch aufnehmen
void AddressBook::Insert(const string& name, const string& phone, const string& email)
{
    // Map benötigt zum Einfügen ein entsprechendes pair
    std::pair<string,Entry> toInsert(name,Entry(phone,email));
    // pair mit den Daten einfügen
    std::pair<bookmap::iterator,bool> success = theBook.insert(toInsert);
    // Da wir nur eine Map haben sind keine doppelten Einträge erlaubt
    if (!success.second)
        cout << name << " konnte nicht eingefuegt werden!\n";
}
// Eintrag aus Adressbuch entfernen
void AddressBook::Remove(const string& name)
{
    // Eintrag suchen
    bookmap::iterator iter = theBook.find(name);
    if (iter == theBook.end())
        cout << name << " nicht im Adressbuch vorhanden!\n";
    else
        // Wenn gefunden, dann löschen
        theBook.erase(iter);
}
// Eintrag abändern
bool AddressBook::Update(const string& name, const string& phone_, const string& email_)
{
    bool success = false;
    // Eintrag suchen
    bookmap::iterator iter = theBook.find(name);
    // Falls gefunden
    if (iter != theBook.end())
    {
        // Telefon-Nummer und Email korrigieren
        iter->second.phone = phone_;
        iter->second.email = email_;
        success = true;
    }
    return success;
}
// Ausgabe des gesamten Adressbuchs
// I.A. kann noch kein const-Objekt übergeben werden da hierfür ein anderer,
// (noch nicht behandelter) Iteratortyp (const_iterator) benötigt wird
std::ostream& operator << (std::ostream& os, AddressBook& abook)
{
    AddressBook::bookmap::iterator iter;
    // Komplettes Adressbuch durchlaufen und ausgeben
    for (iter=abook.theBook.begin(); iter!= abook.theBook.end(); ++iter)
    {
        os << "Name: " << iter->first << '\n'
           << "Tel : " << iter->second.phone
           << ", Email: " << iter->second.email << endl;
    }
    return os;
}

// main() Funktion
int main()
{
    // Adressbuch dynamisch anlegen
    AddressBook *pAddr = new AddressBook;

    // Einige Einträge hinzufügen
    pAddr->Insert("Emil Maier", "0111/4545", "ema@sonst.net");
    pAddr->Insert("Agathe Maier", "0111/4545", "agma@sonst.net");
    pAddr->Insert("Franzi Xelsbrot", "08888/1234", "frax@kostnix.de");
    pAddr->Insert("Gustav Gans", "09999/1111", "guga@lucky.com");

    // Komplettes Adressbuch ausgeben
    cout << "Adressbuch enthaelt " << pAddr->size() << " Eintraege\n";
    cout << *pAddr;

    // Eintrag abändern
    cout << "Aendere Telefon-Nummer von Gustav Gans:\n";
    pAddr->Update("Gustav Gans", "09999/7777", "guga@lucky.com");
    // Und nur geänderten Eintrag ausgeben
    cout << "Neuer Eintrag ist:\n";
    pAddr->PrintAddress("Gustav Gans");

    // Eintrag entfernen
    cout << "Entferne Franzi Xelsbrot:\n";
    pAddr->Remove("Franzi Xelsbrot");

    // Nochmals komplettes Adressbuch ausgeben
    cout << "Neues Adressbuch enthaelt " << pAddr->size() << " Eintraege:\n";
    cout << *pAddr;
    
    // Adressbuch löschen
    delete pAddr;
}