C# :: Aufgabe #308

1 Lösung Lösung öffentlich

Postleitzahl (PLZ) zu erstellen

Anfänger - C# von Gelöschte Person - 22.04.2020 um 16:35 Uhr
Die Idee dieses Programmes soll sein, ein Nachschlagewerk für österreichische Postleitzahlen zu erstellen.
Repräsentativ sollen 9 beliebige Postleitzahlen, eins pro Bundesland, hardcoded eingetragen werden.
Jede PLZ besteht aus einer Zahl, die auf keinen Fall doppelt vorkommen darf und einem eindeutigen Stadtnamen, welcher anders als die Zahl doppelt vorkommen darf (z.B. 1010 Wien, 1020 Wien)
Überlegen Sie sich zuerst gut welchen geeigneten Datentyp Sie verwenden, in den Sie alle Daten strukturiert speichern können. Ich nenne diesen Datentyp im folgenden immer Datensatz.

Erstellen Sie sich für jeden der nachfolgenden Überschriften einen Menüpunkt in ihrem Programm.

z.B. Ausgabe Konsole:
0 - Exit
1 - PLZ erzeugen …

PLZ erzeugen
Es soll möglich sein eine beliebige Anzahl an PLZ zum Datensatz hinzufügen zu können. Ist die PLZ bereits vorhanden, so soll erst mit dem geheimen PIN 1234 das Ändern des Eintrages erlaubt werden. Fragen Sie unbedingt, ob eine Änderung (nur Name) vorgenommen werden soll.
Bedenken Sie, dass eine PLZ in Österreich immer aus genau 4 Zahlen besteht.

PLZ anzeigen
Es soll möglich sein alle PLZ aus dem Datensatz auf einmal auszugeben, um sich die passende zu finden. Sortieren Sie unbedingt den Datensatz nach jedem neuen Eintrag nach der PLZ.

PLZ suchen
Beim Suchen soll es möglich sein einzelne oder mehrere PLZ aufzulisten. Wird bspw. 1010
eingegeben so soll 1010 Wien (PLZ inkl. Name) ausgegeben werden. Wird nur 1 eingegeben und
gesucht, so sollen alle PLZ inkl Name mit 1 beginnend ausgegeben werden. Wird 10 eingegeben, so
sollen alle PLZ inkl. Name mit 10 beginnend ausgegeben werden usw.
Optional: Wird Wien eingegeben, so sollen alle Wiener PLZ aufgelistet werden.
Das Programm darf bei der Suche keinesfalls abstürzen!

Erweiterung
Erweitern Sie nun das Programm um folgende Funktion:
Es soll nach einer Adresse gefragt werden. Erst Adresszeile, dann PLZ, dann Stadt. Eine Adresse,
besteht immer aus einer Adresszeile einer PLZ und einer Stadt.
Ist die PLZ aus dem Datensatz bekannt, soll gar nicht mehr nach dem Stadtnamen gefragt und
automatisch vervollständigt werden. Außerdem soll die eingegebene Adresse ausgegeben und vom
User kontrolliert werden. Zudem soll diese direkt in eine Liste gespeichert werden, wenn diese
korrekt ist. Selbstverständlich soll in der Liste der Städtename ebenfalls hinterlegt sein.
War die PLZ nicht bekannt, soll diese in den Datensatz für die Zukunft gespeichert werden, nachdem
die Korrektheit der Adresse bestätigt wurde.
Geben Sie abschließend alle Adressen aus der Liste, sowie alle PLZ aus dem Datensatz aus.

Lösungen:

vote_ok
von JKooP (3200 Punkte) - 03.05.2020 um 15:29 Uhr
NET Core 3.x

Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace CS_Aufgabe_308_PLZ
{
    public enum Auswahl
    {
        Beenden = 0,
        Adresse_Einlesen,
        PLZ_Speichern,
        Alle_PLZ_Ausgeben,
        Alle_Adressen_Ausgeben,
        Bestimmte_PLZ_Suchen,
        Bestimmten_Ort_Suchen
    }
    public struct Adresse
    {
        public string Strasse { get; set; }
        public string Plz { get; set; }
        public string Ort { get; set; }
    }

    class Program
    {
        private const string Pin = "1234";
        private static string _strasse;
        private static string _plz;
        private static string _ort;
        private static readonly List<Adresse> _lstAdressen = new List<Adresse>();
        private static bool _fehlerSpeichern = false;

        private static readonly SortedDictionary<string, string> _dicPlz = new SortedDictionary<string, string>()
        {
            { "7000", "Eisenstadt" },
            { "9061",  "Klagenfurt" },
            { "3104",  "Sankt Pölten" },
            { "4030",  "Linz" },
            { "4040",  "Linz" },
            { "4005",  "Linz" },
            { "5023",  "Salzburg" },
            { "8010",  "Graz" },
            { "6025",  "Innsbruck" },
            { "6911",  "Bregenz" },
            { "1140",  "Wien" },
            { "1120",  "Wien" },
            { "1110",  "Wien" }
        };

        static void Main(string[] args)
        {
            while (true)
            {
                _fehlerSpeichern = false;

                AuswahlSchreiben();

                Console.Write("\nIhre Auswahl: ");
                if (int.TryParse(Console.ReadLine(), out int input) == false) input = -1;

                switch (input)
                {
                    case (int)Auswahl.Beenden:
                        return;
                    case (int)Auswahl.Adresse_Einlesen:
                        AdresseEinlesen(true);
                        break;
                    case (int)Auswahl.PLZ_Speichern:
                        AdresseEinlesen(false);
                        break;
                    case (int)Auswahl.Alle_PLZ_Ausgeben:
                        AllePlzAusgeben();
                        break;
                    case (int)Auswahl.Alle_Adressen_Ausgeben:
                        AlleAdressenAusgeben();
                        break;
                    case (int)Auswahl.Bestimmte_PLZ_Suchen:
                        PlzSuchenUndAusgeben();
                        break;
                    case (int)Auswahl.Bestimmten_Ort_Suchen:
                        OrtSuchenUndAusgeben();
                        break;
                    default:
                        continue;
                }
            }
        }

        static void AuswahlSchreiben()
        {
            for (int i = 0; i < Enum.GetValues(typeof(Auswahl)).Cast<Auswahl>().Count(); i++)
            {
                Console.WriteLine($"({i}) {Enum.GetName(typeof(Auswahl), i)}");
            }
        }

        static void AdresseEinlesen(bool mitStrasse)
        {
            var r_strasse = new Regex(@"^[A-ZÄÖÜa-zäöüß]+[ \-]+\w+");
            var r_plz = new Regex(@"\b\d{4}\b");
            var r_ort = new Regex(@"\b[A-ZÄÖÜa-zäöüß]+$");
            var strasse = mitStrasse ? "Straße + Hausnummer, " : "";

            Console.Write($"Bitte {strasse}PLZ und Ort eingeben: ");
            var input = Console.ReadLine();

            if (r_plz.IsMatch(input))
            {
                _plz = r_plz.Match(input).ToString();
            }
            else
            {
                Console.WriteLine("Die PLZ hat nicht das richtige Format!\n");
                return;
            }

            if (!r_ort.IsMatch(input))
            {
                if (_dicPlz.ContainsKey(_plz))
                {
                    _ort = _dicPlz[_plz];
                }
                else
                {
                    Console.WriteLine("PLZ nicht bekannt!");
                    return;
                }
            }
            else 
            {
                _ort = r_ort.Match(input).ToString();
                PlzSpeichern();
            }

            if (mitStrasse && r_strasse.IsMatch(input))
            {
                _strasse = r_strasse.Match(input).ToString();
                
                if (!_fehlerSpeichern)
                {
                    _lstAdressen.Add(new Adresse { Strasse = _strasse, Plz = _plz, Ort = _ort });
                    Console.WriteLine($"\nFolgende Adresse wurde angelegt: {_strasse} {_plz} {_ort}\n");
                }
            }
        }

        static void OrtSuchenUndAusgeben()
        {
            Console.Clear();
            Console.Write("Bitte Ort eingeben: ");
            var s = Console.ReadLine().ToLower();
            _dicPlz.Where(x => x.Value.ToLower().Contains(s)).Select(x => new {Ort= x.Value , PLZ = x.Key})
                .OrderBy(x => x.Ort).ThenBy(x => x.PLZ).ToList().ForEach(Console.WriteLine);
            Console.WriteLine();
        }

        static void PlzSuchenUndAusgeben()
        {
            Console.Clear();
            Console.Write("Bitte PLZ eingeben: ");
            var s = Console.ReadLine();
            _dicPlz.Where(x => x.Key.StartsWith(s)).ToList().ForEach(x => Console.WriteLine(x));
            Console.WriteLine();
        }

        static void AllePlzAusgeben()
        {
            Console.Clear();
            if (_dicPlz.Count == 0)
            {
                Console.WriteLine("Kein Eintrag vorhanden!\n");
                return;
            }
            foreach (var item in _dicPlz)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine();
        }

        static void AlleAdressenAusgeben()
        {
            Console.Clear();
            if (_lstAdressen.Count == 0)
            {
                Console.WriteLine("Kein Eintrag vorhanden!\n");
                return;
            }
            foreach (var item in _lstAdressen)
            {
                Console.WriteLine($"{(item.Strasse, item.Plz, item.Ort)}");
            }
            Console.WriteLine();
        }

        static void PlzSpeichern()
        {
            Console.Clear();

            if (_dicPlz.ContainsKey(_plz))
            {
                Console.WriteLine($"Die PLZ '{ _plz }' wird bereits mit dem Ort '{ _dicPlz[_plz] }' verwendet!");
                Console.Write($"Wollen Sie die PLZ '{ _plz }' mit dem neuen Ort '{ _ort }' überschreiben? (j/n): ");
                if (Console.ReadLine().ToLower() == "j")
                {
                    Console.Write("Bitte Pin eingeben: ");
                    if (Console.ReadLine() == Pin)
                    {
                        _dicPlz[_plz] = _ort;
                        Console.WriteLine("Der Ort wurde geändert!\n");
                    }
                    else
                    {
                        Console.WriteLine("Falsche Pin! Vorgang wurde abgebrochen.");
                        _fehlerSpeichern = true;
                        return;
                    }
                }
                else
                {
                    _fehlerSpeichern = true;
                    return;
                }
            }
            else
            {
                _dicPlz.Add(_plz, _ort);
                Console.WriteLine($"'{_plz} {_ort}' wurde angelegt!\n");
            }
        }
    }
}