From ba25632650fd3143813999eed1c80f50ea5cfd4b Mon Sep 17 00:00:00 2001 From: MrGeorgen Date: Thu, 14 Oct 2021 16:21:48 +0200 Subject: [PATCH] a2 Quelltext Dokumentation --- .../{Aufgabe1.md => README.md} | 0 a2-Vollgeladen/src/main.c | 77 ++++++++++++++++--- 2 files changed, 65 insertions(+), 12 deletions(-) rename a1-Schiebeparkplatz/{Aufgabe1.md => README.md} (100%) diff --git a/a1-Schiebeparkplatz/Aufgabe1.md b/a1-Schiebeparkplatz/README.md similarity index 100% rename from a1-Schiebeparkplatz/Aufgabe1.md rename to a1-Schiebeparkplatz/README.md diff --git a/a2-Vollgeladen/src/main.c b/a2-Vollgeladen/src/main.c index 3becd91..fabba29 100644 --- a/a2-Vollgeladen/src/main.c +++ b/a2-Vollgeladen/src/main.c @@ -4,72 +4,125 @@ #include #include +// der Makro "panicio" gibt einen Ein-/ Ausgabefehler aus und beendet das Programm mit einem Fehlercode. #define panicio {\ perror(*filepath);\ return 1;\ } + +/* Ein Makro, der die nächste Zahl der Eingabedatei zurückgibt. + * In der Eingabedatei werden die Zahlen immer durch ein anderes Zeichen getrennt (Leerzeichen, newline-character, Punkt). + * Da die Funktion "strtol" den Zeiger "nextnumber" immer auf das erste Zeichen nach der verarbeiteten Zahl zeigen lässt, + * muss "nextnumber" um eins erhöht werden, um auf die nächste Zahl zu zeigen.*/ #define getNumber strtol(nextnumber + 1, &nextnumber, 10) +// Struktur, die ein Hotel darstellt. struct hotel { uint_least16_t minutes; uint_least8_t rating; }; int main(int argc, char *argv[]) { + // Schleife iteriert über die Argumente, die Dateipfade sind. for(char **filepath = argv + 1; filepath - argv < argc; ++filepath) { - printf("%s:\n", *filepath); uint_least16_t numberHotels, totalMinutes; struct hotel *hotels; + printf("%s:\n", *filepath); { char *inputText; { - FILE *inputFile = fopen(*filepath, "rb"); - if(inputFile == NULL) panicio; + FILE *inputFile = fopen(*filepath, "r"); // öffnet die Datei + if(inputFile == NULL) panicio; // gibt möglichen Fehler aus bool success; + + /* Die Funktion "acl_ReadTextFile" liest die Datei aus und gibt den Inhalt als String zurück. + * Die Variable "success" wird je nach Erfolg modifiziert.*/ inputText = acl_ReadTextFile(inputFile, &success); if(!success) panicio; - fclose(inputFile); + fclose(inputFile); // schließt die Datei } { char *nextnumber; + + /* Die Anzahl der Hotels muss noch den Makro "getNumber" verarbeitet werden, + * da dieser vorraussetzt, das der Zeiger "nextnumber" bereits definiert ist. + * Zudem wird noch Eins addiert, weil noch ein "Hotel" hinzugefügt wird, + * das den Zielpunkt darstellt.*/ numberHotels = strtol(inputText, &nextnumber, 10) + 1; - totalMinutes = getNumber; + totalMinutes = getNumber; // gesamte Fahrzeit + + // belegt den Speicher für ein Array mit allen Hotels hotels = malloc(numberHotels * sizeof *hotels); + + // jedem Hotel des Arrays werden die jeweiligen Werte zugewiesen for(uint_least16_t i = 0; i < numberHotels; ++i) { hotels[i].minutes = getNumber; + + /* "strtol" verarbeitet nur ganze Zahlen. Deshalb werden die beiden Ziffern einzeln + * verarbeitet. Da für die Bewertung ein Integer-Typ verwendet wird, + * ist die resultierende Bewertung das zehnfache der Bewertung in der Eingabedatei. + * Diese wird bei der Ausgabe wieder umgewandelt.*/ hotels[i].rating = 10 * getNumber; hotels[i].rating += getNumber; } - hotels[numberHotels - 1] = (struct hotel){ .minutes = totalMinutes, .rating = 50}; } - free(inputText); + free(inputText); // freigeben des Speichers der ausgelesenen Textdatei + + /* fügt den Zielort als "Hotel" hinzu, da der Algorithmus ein Hotel erst dann berücksichtigt, + * wenn das nächste Hotel außer Fahrtreichweite ist. Es gibt allerdings kein nächstes Hotel + * vom letzten Hotel, weshalb das letzte Hotel als Haltepunkt nicht in Betracht gezogen wird. + * Also wird der Zielort als "Hotel" hinmzugefügt, damit auch das letzte richtige Hotel + * verwendet werden kann.*/ + hotels[numberHotels - 1] = (struct hotel){ .minutes = totalMinutes, .rating = 50}; } { - struct hotel hotelRoute[4]; - uint_least8_t stoppedHotels; + struct hotel hotelRoute[4]; // speichert die Hotels, an denen gehalten wird + uint_least8_t stoppedHotels; // Anzahl der gemachten Stops + + /* In der Schleife wird versucht eine Route mit der Bewertung von mindestens 50 zu bilden. + * Wenn dies nicht erfolgrecih ist, wird es mit 49, 48, ... versucht bis eine Route gefunden wurde.*/ { uint_least8_t rating = 50; do { + // Minuten die das letzte Hotel, bei dem angehalten wurde, vom Start entfertn ist uint_least16_t lastHotelMinutes = 0; + // Zeiger zum letzten Hotel, dessen Bewertung mindestens "rating" ist. struct hotel *possibleStop = NULL; - stoppedHotels = 0; + stoppedHotels = 0; // setzt Anzahl der Stops zurück + + // iteriert über die Hotels for(struct hotel *currentHotel = hotels; currentHotel - hotels < numberHotels; ++currentHotel) { + + /* Wenn das aktuelle Hotel mehr als 360 Minuten vom letzten Hotel entfernt ist, + * muss das letzte Hotel verwendet werden an dem das Halten möglich war.*/ if(currentHotel->minutes - lastHotelMinutes > 360) { + /* Wenn das Halten nicht möglich ist oder bereits schon viermal + * gehalten wurde, muss es mit einer niedrigeren Bewertung versucht + * werden.*/ if(possibleStop == NULL || stoppedHotels >= 4) break; + // hängt das Hotel der Route an hotelRoute[stoppedHotels] = *possibleStop; lastHotelMinutes = possibleStop->minutes; + // springt in der Schleife zurück zum Hotel, an dem gestoppt wurde currentHotel = possibleStop; ++stoppedHotels; } + // Wenn die Bewertung hoch genug ist, kann gestoppt werden. if(currentHotel->rating >= rating) possibleStop = currentHotel; } --rating; + /* Schleife läuft solange "rating" mindestens Eins ist, da es keine niedrigeren Bewertungen + * gibt. Wenn das letzte Hotel höchtens 360 Minuten vom Zielort entfernt ist, wurde + * erfolgreich eine Route gefunden und die Schleife wird beendet. Allerdings wird dies nur + * überprüft, wenn überhaupt an einem Hotel gehalten wurde, um den Zugriff auf nicht + * definierten Speicher zu vermeiden.*/ } while(rating && (!stoppedHotels || totalMinutes - hotelRoute[stoppedHotels - 1].minutes > 360)); } + // gibt die Hotels der Route aus. for(struct hotel *hotelPrint = hotelRoute; hotelPrint - hotelRoute < stoppedHotels; ++hotelPrint) { - printf("Entfernung vom Start: %" PRIuLEAST16 " Minuten, Bewertung: %" PRIuLEAST8 "\n", hotelPrint->minutes, hotelPrint->rating); + printf("Entfernung vom Start: %" PRIuLEAST16 " Minuten, Bewertung: %.1f\n", hotelPrint->minutes, (double)hotelPrint->rating / 10); } } - free(hotels); + free(hotels); // gibt den Speicher des Hotelarrays frei } }