diff --git a/Workbook/Makefile b/Workbook/Makefile new file mode 100644 index 0000000..bf84aa3 --- /dev/null +++ b/Workbook/Makefile @@ -0,0 +1,36 @@ +## +# TH WWS +# +# @file +# @version 0.1 +CC = gcc +CFLAGS ?= -Wall -Wextra -Iinclude -fomit-frame-pointer -O2 + +SRC_DIR = src +INCLUDE_DIR = include +BUILD_DIR = build +TARGET = WWS_System + +SRC_FILES = $(wildcard $(SRC_DIR)/*.c) +OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRC_FILES)) + +.PHONY: all clean + +all: $(BUILD_DIR) $(TARGET) + +# Link all the files into the final executable +$(TARGET): $(OBJ_FILES) + $(CC) $(OBJ_FILES) -o $@ + +# Compile source- and object files +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) + $(CC) $(CFLAGS) -c $< -o $@ + +#Ensure the build directory exists +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + +# Clean build and target +clean: + rm -Rf $(BUILD_DIR) $(TARGET) +# end diff --git a/Workbook/include/util.h b/Workbook/include/util.h new file mode 100644 index 0000000..fd9593d --- /dev/null +++ b/Workbook/include/util.h @@ -0,0 +1,20 @@ +#ifndef UTIL_H_ +#define UTIL_H_ + +#include +#include +#include +#include +#include +#include + +// Magic number to be returned in case something goes wrong. Lets the program know an error occured. This is kind of a hack. +#define ERRORRETURN 10787253 + +void null_terminate(char str[]); +bool is_num(char *str); +bool is_int(char *str); +int get_clean_int(); +double get_clean_num(); +bool is_safe(const char* string); +#endif // UTIL_H_ diff --git a/Workbook/include/wws.h b/Workbook/include/wws.h new file mode 100644 index 0000000..dd41489 --- /dev/null +++ b/Workbook/include/wws.h @@ -0,0 +1,44 @@ +#ifndef WWS_H_ +#define WWS_H_ + +#include "util.h" + +#define ARRSIZE 4096 +#define EXITVAL 15326 + +typedef struct Product Product; +typedef struct Customer Customer; + +struct Product { + int id; + char* name; + double price; + int amount; +}; + +struct Customer { + char* name; + int id; + // NOTE: Always NULL-initialize this!! + Product* products[ARRSIZE]; +}; + +// Implementation details +int read_id(); +char* read_name(); +double read_price(); +int read_amount(); +int find_first_free_index(Customer customer); +int find_product(Customer customer, int id); // Returns index of product +int find_customer(int id); // Returns index in the customers array + +// Top-Level functions +int add_product(); +int print_product(); +int add_customer(); +int print_customer(); +int menu(); + +extern Customer customers[ARRSIZE]; + +#endif // WWS_H_ diff --git a/Workbook/src/main.c b/Workbook/src/main.c new file mode 100644 index 0000000..87e35af --- /dev/null +++ b/Workbook/src/main.c @@ -0,0 +1,13 @@ +#include "wws.h" + +int main() { + Customer customers[ARRSIZE]; + memset(customers, 0, sizeof(Customer)); + while(true) { + int exitcode = menu(); + if (exitcode == EXITVAL) { + return 0; + } + } + return 0; +} diff --git a/Workbook/src/util.c b/Workbook/src/util.c new file mode 100644 index 0000000..d490830 --- /dev/null +++ b/Workbook/src/util.c @@ -0,0 +1,95 @@ +#include "util.h" + +bool is_num(char *str) { + if (*str == '+' || *str == '-') { + str++; + } + if (*str == '\0') { + return false; + } + while (*str) { + if (!isdigit((unsigned char)*str) || !(*str == '.')) { + return true; + } + str++; + } + + return false; +} + +bool is_int(char *str) { + if (*str == '+' || *str == '-') { + str++; + } + if (*str == '\0') { + return false; + } + while (*str) { + if (!isdigit((unsigned char)*str)) { + return true; + } + str++; + } + + return true; +} + +double get_clean_num() { + char *buffer; + size_t bufsize = 0; + char *eptr; + + ssize_t input_length = getline(&buffer, &bufsize, stdin); + if (input_length == -1) { + printf("Fehler beim lesen des inputs.\n"); + free(buffer); + buffer = NULL; + return ERRORRETURN; + } + + if (is_num(buffer)) { + return strtod(buffer, &eptr); + } + + printf("Deine Eingabe ist keine Zahl.\n"); + free(buffer); + buffer = NULL; + return ERRORRETURN; +} + +int get_clean_int() { + char *buffer; + size_t bufsize = 0; + + ssize_t input_length = getline(&buffer, &bufsize, stdin); + if (input_length == -1) { + printf("Fehler beim lesen des inputs.\n"); + free(buffer); + buffer = NULL; + return ERRORRETURN; + } + + if (is_int(buffer)) { + return atoi(buffer); + } + + printf("Deine Eingabe ist keine ganze Zahl.\n"); + free(buffer); + buffer = NULL; + return ERRORRETURN; +} + +bool is_safe(const char* string) { + if (string == NULL) { + return false; + } + + + for (size_t i = 0; string[i] != '\0'; ++i) { + if (string[i] == '%') { + return false; + } + } + + return true; +} diff --git a/Workbook/src/wws.c b/Workbook/src/wws.c new file mode 100644 index 0000000..bc5b821 --- /dev/null +++ b/Workbook/src/wws.c @@ -0,0 +1,195 @@ +#include "wws.h" +#include "util.h" +#include + +int read_id() { + printf("Produktnummer: "); + int input = get_clean_int(); + if (input != ERRORRETURN) {return input;} + else { + printf("Die eingegebene Produktnummer ist keine Zahl.\n"); + return ERRORRETURN; + } +} + +char* read_name() { + char* buffer; + size_t buffsize = 0; + printf("Name: "); + ssize_t input_length = getline(&buffer, &buffsize, stdin); + if (input_length == -1) { + printf("Fehler beim lesen.\n"); + free(buffer); + buffer = NULL; + } + return buffer; +} + +double read_price() { + printf("Preis: "); + double price = get_clean_num(); + if (price == ERRORRETURN) {return ERRORRETURN;} + return price; +} + +int read_amount() { + printf("Anzahl: "); + int amount = get_clean_int(); + if (amount == ERRORRETURN) {return ERRORRETURN;} + return amount; +} + +int find_first_free_index(Customer customer) { + for (int i = 0; i < ARRSIZE; i++) { + if (customer.products[i] == NULL) { + return i; + } + } + printf("Für diesen Kunden können keine weiteren Produkte hinzugefügt werden.\n"); + return ERRORRETURN; +} + +int find_product(Customer customer, int id) { + for (int i = 0; i < ARRSIZE; i++) { + if (customer.products[i]->id == id) {return i;} + } + return ERRORRETURN; +} + +int find_customer(int id) { + for (int i = 0; i < ARRSIZE; i++) { + if (customers[i].id == id) {return id;} + } + return ERRORRETURN; +} + +int add_product() { + Product* new_product = (Product*) malloc(sizeof(Product)); + printf("**********************\n"); + printf("* WWS Produkteingabe *\n"); + printf("**********************\n"); + printf("Bitte geben Sie ihre Kundennumer ein: "); + int customer_id = get_clean_int(); + if (customer_id == ERRORRETURN) {return ERRORRETURN;} + Customer* customer = &customers[find_customer(customer_id)]; + new_product->id = read_id(); + if (new_product->id == ERRORRETURN) {return ERRORRETURN;} + if (find_product(*customer, new_product->id)) { + printf("Es existiert bereits ein Produkt mit dieser ID.\n"); + return ERRORRETURN; + } + new_product->name = read_name(); + if (!is_safe(new_product->name)) { + printf("Der eingegebene Produktname enthält verbotene Zeichen.\n"); + return ERRORRETURN; + } + new_product->price = read_price(); + if (new_product->price == ERRORRETURN) {return ERRORRETURN;} + new_product->amount = read_amount(); + if (new_product->amount == ERRORRETURN) {return ERRORRETURN;} + int free_index = find_first_free_index(*customer); + if (free_index == ERRORRETURN) {return ERRORRETURN;} + customer->products[free_index] = new_product; + return 0; +} + +int print_product() { + printf("**********************\n"); + printf("* WWS Produktausgabe *\n"); + printf("**********************\n"); + printf("Bitte geben Sie Ihre Kundennummer ein: "); + int customer_id = get_clean_int(); + if (customer_id == ERRORRETURN) {return ERRORRETURN;} + printf("Bitte geben Sie die gewünschte Produktnummer ein: "); + int product_id = get_clean_int(); + if (product_id == ERRORRETURN) {return ERRORRETURN;} + int product_index = find_product(customers[customer_id], product_id); + if (product_index == ERRORRETURN) { + printf("Die Produktnummer konnte nicht gefunden werden.\n"); + return ERRORRETURN; + } + + Product* product = customers[customer_id].products[product_index]; + printf("Produktnummer: %d\n", product->id); + printf("Produktname: %s\n", product->name); + printf("Preis: %f\n", product->price); + printf("Anzahl: %d\n", product->amount); + return 0; +} + +int add_customer() { + Customer* new_customer = (Customer*) malloc(sizeof(Customer)); + if (new_customer == NULL) { + printf("Fehler beim Speicher zuweisen"); + return ERRORRETURN; + } + printf("*********************\n"); + printf("* WWS Kundeneingabe *\n"); + printf("*********************\n"); + printf("Kundennummer: "); + new_customer->id = get_clean_int(); + if (new_customer->id == ERRORRETURN) {return ERRORRETURN;} + printf("Kundenname: "); + new_customer->name = read_name(); + if (!is_safe(new_customer->name)) { + printf("Der eigegebene Kundenname enthält verbotene Zeichen.\n"); + return ERRORRETURN; + } + for (int i = 0; i < ARRSIZE; i++) { + if (customers[i].id == -1) { + customers[i] = *new_customer; + return 0; + } + } + printf("Es können keine weiteren Kunden hinzugefügt werden.\n"); + return ERRORRETURN; +} + +int print_customer() { + printf("**********************\n"); + printf("* WWS Kundenausgabe *\n"); + printf("**********************\n"); + printf("Bitte geben Sie ihre Kundennummer ein: "); + int id = get_clean_int(); + if (id == ERRORRETURN) {return ERRORRETURN;} + int wanted_index = find_customer(id); + if (wanted_index == ERRORRETURN) { + printf("Die eingegebene Kundennummer konnte nicht gefunden werden."); + return ERRORRETURN; + } + Customer customer = customers[wanted_index]; + printf("Kundennumer: %d\n", customer.id); + printf("Name: %s\n", customer.name); + return 0; +} + +int menu() { + printf("**********************\n"); + printf("* WWS Menüsystem *\n"); + printf("**********************\n"); + printf("1: Produkteingabe\n"); + printf("2: Produktausgabe\n"); + printf("3: Kundeneingabe\n"); + printf("4: Kundenausgabe\n"); + printf("5: Verlassen\n"); + printf("Auswahl: "); + int input = get_clean_int(); + switch (input) { + case 1: + add_product(); + break; + case 2: + print_product(); + break; + case 3: + add_customer(); + break; + case 4: + print_customer(); + break; + case 5: + printf("Das System wird verlassen...\n"); + return EXITVAL; + } + return 0; +}