#include #include #include #include "List.h" #define STORAGEFILE "TextFileStorage.txt" #define SEPARATOR "|" // show a list of options and return the one the user chose int user_choice; int Menu(void) { printf("Menu:\n\n"); printf("1. Add entry\n"); printf("2. View entries\n"); printf("3. Edit entry\n"); printf("4. Delete entry\n"); printf("5. Exit\n\n"); scanf("%d\n", &user_choice); return user_choice; } // add an entry to the database void AddEntry(LIST *list, int edit) { int i, c, y, z, editnum, bufsize = 256; char numreadbuf[32] = {0}; char *readbuf, *p, *item; if (edit == 0) printf("Add Entry:\n\n"); else { printf("Edit Entry:\n\n"); printf("Enter entry number to edit:\n"); // read the user input as a fixed length string (for error handling) if (fgets(numreadbuf, sizeof(numreadbuf)-1, stdin) == NULL) { printf("Invalid input\n\n"); return; } // convert the string to an integer and check it's within a valid range if (sscanf(numreadbuf, "%d", &editnum) != 1 || editnum < 1 || editnum > list->nItems) { printf("Invalid input\n\n"); return; } } printf("Enter X (string):\n"); // allocate an initial amount of memory to store X in readbuf = malloc(bufsize); if (readbuf == NULL) { printf("Memory allocation error\n\n"); return; } // read a character at a time and append it to the memory for (i=0; ;i++) { c = getchar(); if (c == '\r') { readbuf[i] = '\0'; // set end of string when carriage return reached } else if (c == '\n') { readbuf[i] = '\0'; break; } else { readbuf[i] = c; } // length of input exceeds the size of memory allocated so allocate more if (i == bufsize-1) { p = realloc(readbuf, bufsize += 256); if (p == NULL) { free(readbuf); printf("Memory reallocation error\n\n"); return; } readbuf = p; } } printf("Enter Y (integer < 20):\n"); // read the user input as a fixed length string (for error handling) if (fgets(numreadbuf, sizeof(numreadbuf)-1, stdin) == NULL) { printf("Invalid input\n\n"); free(readbuf); return; } // convert the string to an integer and check it's within a valid range if (sscanf(numreadbuf, "%d", &y) != 1 || y >= 20) { printf("Invalid input\n\n"); free(readbuf); return; } printf("Enter Z (integer < 10):\n"); // read the user input as a fixed length string (for error handling) if (fgets(numreadbuf, sizeof(numreadbuf)-1, stdin) == NULL) { printf("Invalid input\n\n"); free(readbuf); return; } // convert the string to an integer and check it's within a valid range if (sscanf(numreadbuf, "%d", &z) != 1 || z >= 10) { printf("Invalid input\n\n"); free(readbuf); return; } // allocate memory for item to enter list item = malloc(bufsize + 32); if (item == NULL) { free(readbuf); printf("Memory allocation error\n\n"); return; } // build the item from existing values sprintf(item, "%s%s%d%s%d", readbuf, SEPARATOR, y, SEPARATOR, z); if (edit == 0) ListAddItem(list, item); // add item to list else ListReplaceItem(list, editnum-1, item); // edit item in list // show user what was entered printf("Entered: %s\n\n", item); // free memory free(item); free(readbuf); } void DeleteEntry(LIST *list) { int n; char numreadbuf[32] = {0}; printf("Delete Entry:\n\n"); printf("Enter entry number to delete:\n"); // read the user input as a fixed length string (for error handling) if (fgets(numreadbuf, sizeof(numreadbuf)-1, stdin) == NULL) { printf("Invalid input\n\n"); return; } // convert the string to an integer and check it's within a valid range if (sscanf(numreadbuf, "%d", &n) != 1 || n < 1 || n > list->nItems) { printf("Invalid input\n\n"); return; } // delete the entry from the list ListDeleteItem(list, n-1); printf("Entry deleted\n\n"); } // list each entry in the list void ViewEntries(LIST *list) { int i; printf("View Entries:\n\n"); // cycle through the list printing each entry for (i=0; inItems; i++) { printf("%d. %s\n", i+1, list->pItems[i]); } putchar('\n'); } // execution starts here int main(int argc, char *argv[]) { LIST list; int ret; // initalise the list ListInit(&list); // load list file to memory (if exists) if ((ret = ListLoadFile(&list, STORAGEFILE)) != 0) { printf("Error %d loading file\n", ret); } // show the menu asking for input until told to exit while ((ret = Menu()) != 5) { // exit command if (ret == 5) break; // handle each option switch (ret) { // add entry case 1: AddEntry(&list, 0); ListSaveFile(&list, STORAGEFILE); break; // view entries case 2: ViewEntries(&list); break; // edit entry case 3: AddEntry(&list, 1); ListSaveFile(&list, STORAGEFILE); break; // delete entry case 4: DeleteEntry(&list); ListSaveFile(&list, STORAGEFILE); break; } } // destroy the list, freeing memory ListCleanup(&list); return 0; }