From 9ee68f1bc403b6820316b3e1f1343c1a7afb54b4 Mon Sep 17 00:00:00 2001 From: paulusja Date: Thu, 12 Nov 2026 07:56:04 +0100 Subject: [PATCH] Add dynamic namesarchive solution as template for queue exercise. --- 08_queue/main.c | 82 ++++++++++++++++++++++++++++ 08_queue/makefile | 16 ++++++ 08_queue/namesarchive.c | 118 ++++++++++++++++++++++++++++++++++++++++ 08_queue/namesarchive.h | 19 +++++++ 4 files changed, 235 insertions(+) create mode 100644 08_queue/main.c create mode 100644 08_queue/makefile create mode 100644 08_queue/namesarchive.c create mode 100644 08_queue/namesarchive.h diff --git a/08_queue/main.c b/08_queue/main.c new file mode 100644 index 0000000..11fd53d --- /dev/null +++ b/08_queue/main.c @@ -0,0 +1,82 @@ +/* + * Vervollständigen Sie das untenstehende Programm, indem Sie das Modul namesarchive in der + * namesarchive.h bzw. namesarchive.c implementieren. + * Die öffentlichen Schnittstellen mit genaueren Details entnehmen Sie der namesarchive.h. + * Das Programm soll das Modul als dynamische Laufzeitbibliothek nutzen. + * + */ + +#include +#include +#include +#include "namesarchive.h" + +#define MAX_BUFFER_LEN 100 + +char *inputName(const char *promptText, char *buffer, unsigned int bufferSize); + +int main() +{ + char buffer[MAX_BUFFER_LEN]; + + while((inputName("Namen hinzufuegen: ", buffer, MAX_BUFFER_LEN) != NULL) && (strlen(buffer) > 0)) + { + if(addName(buffer)) + printf("%s wurde dem Archiv hinzugefuegt.\n", buffer); + else + printf("Fehler! %s konnte nicht hinzugefuegt werden.\n", buffer); + } + + printf("\nNach Eingabe:\n"); + printNames(); + + printf("\nNach Sortierung:\n"); + sortNames(); + printNames(); + printf("\n"); + + while((inputName("Namen sortiert hinzufuegen: ", buffer, MAX_BUFFER_LEN) != NULL) && (strlen(buffer) > 0)) + { + if(addNameSorted(buffer)) + printf("%s wurde dem Archiv hinzugefuegt.\n", buffer); + else + printf("Fehler! %s konnte nicht hinzugefuegt werden.\n", buffer); + } + + printf("\nNach sortierter Eingabe:\n"); + printNames(); + printf("\n"); + + while((inputName("Namen entfernen: ", buffer, MAX_BUFFER_LEN) != NULL) && (strlen(buffer) > 0)) + { + if(removeName(buffer)) + printf("%s wurde aus dem Archiv entfernt.\n", buffer); + else + printf("Fehler! %s konnte nicht gefunden werden.\n", buffer); + } + + printf("\nNach Entfernen:\n"); + printNames(); + + clearArchive(); + + return EXIT_SUCCESS; +} + +char *inputName(const char *promptText, char *buffer, unsigned int bufferSize) +{ + printf("%s", promptText); + if(fgets(buffer, bufferSize, stdin) != NULL) + { + if(buffer[strlen(buffer)-1] == '\n') + buffer[strlen(buffer)-1] = '\0'; + else + while(getchar() != '\n') {} + + return buffer; + } + else + { + return NULL; + } +} \ No newline at end of file diff --git a/08_queue/makefile b/08_queue/makefile new file mode 100644 index 0000000..e8014a9 --- /dev/null +++ b/08_queue/makefile @@ -0,0 +1,16 @@ +namesarchive: main.o libnamesarchive.so + gcc -Wall -o namesarchive main.o libnamesarchive.so + +main.o: main.c + gcc -c -Wall main.c + +namesarchive.o: namesarchive.c namesarchive.h + gcc -c -Wall namesarchive.c + +libnamesarchive.so: namesarchive.o + gcc -shared -o libnamesarchive.so namesarchive.o + +clean: + del /f namesarchive.exe *.o *.so +# Comment line above and uncomment line below for UNIX systems +# rm -f namesarchive *.o *.so \ No newline at end of file diff --git a/08_queue/namesarchive.c b/08_queue/namesarchive.c new file mode 100644 index 0000000..406315d --- /dev/null +++ b/08_queue/namesarchive.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include "namesarchive.h" + +static char **names = NULL; +static unsigned int numberOfNames = 0; + +static int findNameIdx(const char *name); +static void removeNameByIdx(unsigned int idx); +static int compareNames(const void *arg1, const void *arg2); + +// Fügt einen Namen hinzu. Im Fehlerfall (Archiv ist voll) soll 0, ansonsten 1 zurückgegeben werden. +// Ist der angegebene Name länger als die zulässige Namenslänge, wird der Name abgeschnitten hinzugefügt. Rückgabe ist dann 1. +int addName(const char *name) +{ + if(name != NULL) + { + char **oldMemory = names; + names = realloc(names, sizeof(*names) * (numberOfNames + 1)); + + if(names == NULL) + names = oldMemory; + else + { + names[numberOfNames] = malloc(sizeof(*name) * (strlen(name) + 1)); + + if(names[numberOfNames] == NULL) + { + names = realloc(names, sizeof(*names) * numberOfNames); + } + else + { + strncpy(names[numberOfNames], name, strlen(name)+1); + numberOfNames++; + return 1; + } + } + } + return 0; +} + +// Wie addName. Fügt Namen aber direkt sortiert hinzu. Voraussetzung ist ein bereits sortiertes Archiv. +int addNameSorted(const char *name) +{ + return 0; +} + +// Entfernt den angegebenen Namen. Gibt bei Erfolg 1 zurück, ansonsten 0 (Name konnte nicht gefunden werden). +int removeName(const char *name) +{ + int nameIdx = findNameIdx(name); + + if(nameIdx >= 0) + { + removeNameByIdx(nameIdx); + return 1; + } + else + return 0; +} + +int findNameIdx(const char *name) +{ + for(int i = 0; i < numberOfNames; i++) + { + if(strcmp(names[i], name) == 0) + { + return i; + } + } + return -1; +} + +void removeNameByIdx(unsigned int idx) +{ + free(names[idx]); + for(unsigned i = idx+1; i < numberOfNames; i++) + { + names[i-1] = names[i]; + } + numberOfNames--; + names = realloc(names, sizeof(*names) * numberOfNames); +} + +int compareNames(const void *arg1, const void *arg2) +{ + const char *name1 = *((const char **)arg1); + const char *name2 = *((const char **)arg2); + + return strcmp(name1, name2); +} + +// Sortiert die Namen im Archiv aufsteigend. +void sortNames() +{ + qsort(names, numberOfNames, sizeof(names[0]), compareNames); +} + +// Gibt die Namen zeilenweise aus. +void printNames() +{ + for(int i = 0; i < numberOfNames; i++) + { + printf("%s\n", names[i]); + } +} + +void clearArchive() +{ + for(int i = 0; i < numberOfNames; i++) + { + free(names[i]); + } + free(names); + names = NULL; + numberOfNames = 0; +} \ No newline at end of file diff --git a/08_queue/namesarchive.h b/08_queue/namesarchive.h new file mode 100644 index 0000000..f83700c --- /dev/null +++ b/08_queue/namesarchive.h @@ -0,0 +1,19 @@ +#ifndef NAMEARCHIVE_H +#define NAMEARCHIVE_H + +// Fügt einen Namen hinzu. Im Fehlerfall (Archiv ist voll) soll 0, ansonsten 1 zurückgegeben werden. +// Ist der angegebene Name länger als die zulässige Namenslänge, wird der Name abgeschnitten hinzugefügt. Rückgabe ist dann 1. +int addName(const char *name); +// Wie addName. Fügt Namen aber direkt sortiert hinzu. Voraussetzung ist ein bereits sortiertes Archiv. +int addNameSorted(const char *name); +// Entfernt den angegebenen Namen. Gibt bei Erfolg 1 zurück, ansonsten 0 (Name konnte nicht gefunden werden). +int removeName(const char *name); +// Sortiert die Namen im Archiv aufsteigend. +void sortNames(); +// Gibt die Namen zeilenweise aus. +void printNames(); + +// Gibt Resourcen frei +void clearArchive(); + +#endif \ No newline at end of file