From 3a6005c79c4d14e1aad1b95055d3db64d457a0b7 Mon Sep 17 00:00:00 2001 From: Jack-Benny Persson Date: Fri, 19 Jan 2018 06:46:47 +0100 Subject: [PATCH] Initial commit --- lagerhantering-komplett.c | 360 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 lagerhantering-komplett.c diff --git a/lagerhantering-komplett.c b/lagerhantering-komplett.c new file mode 100644 index 0000000..024ab39 --- /dev/null +++ b/lagerhantering-komplett.c @@ -0,0 +1,360 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +/* Makron */ +#define NAMEMAXLENGTH 30 + +/* Globala variabler så att de är tillgängliga både + från main() och de övriga funktionerna. + struct myData används t.ex. både från main() och + new() */ +struct myData +{ + char name[NAMEMAXLENGTH]; + int quantity; + float price; +}; + +char filename[] = "storage.bin"; + +/* Funktionsprototyper */ +void list(struct myData *datap, int numRec); +void search(struct myData *datap, int numRec, char *name); +void modify(struct myData *datap, int numRec, char *name); +void delete(struct myData *datap, int numRec, char *name); +int new(struct myData *datap, int numRec); +void printUsage(char *arg); +void printHeader(void); + + +int main(int argc, char* argv[]) +{ + FILE *fp; /* Filpekare */ + int newart = 0; /* Ska vi skapa en ny artikel? */ + int numRec; /* För antalet för artiklar */ + int create; /* För y/n-fråga */ + int opt; /* För getopt() */ + + /* Skapa en strukturvariabel (en pekare) av struct myData */ + struct myData *data; + + /* Skriv ut hjälptexten och returnera 1 om vi saknar argument */ + if (argc < 2) + { + printUsage(argv[0]); + return 1; + } + + /* Kontrollera om filen finns och är läs- och skrivbar. + Om inte, fråga om vi ska skapa den och börja läsa + in artiklar. access() är ett systemanrop för UNIX-miljöer */ + if ( access(filename, R_OK|W_OK) != 0 ) + { + /* Använd fprintf() för att skriva felmeddelanden + till stderr */ + fprintf(stderr, "Could not open %s\n", filename); + printf("Create the file and start adding records? (y/n): "); + create = getchar(); + if ( create == 'y' ) + { + /* Allokera minne för en struct myData och anropa + sedan new() med en pekare till minnet för att lägga + till artiklar i lagret, en i taget */ + numRec = 1; + data = calloc(numRec, sizeof(struct myData)); + new(data, numRec); + free(data); + return 0; + } + else + return 1; + } + + /* Öppna filen i läsläge */ + fp = fopen(filename, "rb"); + + /* Läs in befintlig data från filen till strukturen */ + fseek(fp, 0, SEEK_END); + numRec = ftell(fp) / sizeof(struct myData); + data = calloc(numRec, sizeof(struct myData)); + rewind(fp); + fread(data, sizeof(struct myData), numRec, fp); + fclose(fp); + + /* Behandla argumenten med getopt() */ + while ((opt = getopt(argc, argv, "hls:m:d:n")) != -1) + { + switch (opt) + { + case 'l': + list(data, numRec); + break; + case 's': + search(data, numRec, optarg); + break; + case 'm': + modify(data, numRec, optarg); + break; + case 'd': + delete(data, numRec, optarg); + break; + case 'n': + newart = 1; + break; + case 'h': + printUsage(argv[0]); + return 0; + default: + printUsage(argv[0]); + return 1; + } + } + + /* Fortsätt här om filen finns och vi valde att lägga + till artiklar */ + if ( newart == 1 ) + { + data = calloc(1, sizeof(struct myData)); + if ( new(data, numRec) == 1 ) + return 1; + } + + /* Här är programmet klart, så frigör minnet och returnera 0 */ + free(data); + return 0; +} + +/* Funktionerna nedan tar en pekare till datatypen struct myData + som första argument. Som andra argument ett heltal som innehåller + antalet artiklar i lagret. */ +void list(struct myData *datap, int numRec) +{ + int i; + printHeader(); + for (i = 0; iname, NAMEMAXLENGTH, stdin); + datap->name[strcspn(datap->name, "\n")] = '\0'; + + if ( strcmp(datap->name, "done") == 0 ) + { + fclose(fp); + return 0; + } + printf("Quantity: "); scanf("%d", &datap->quantity); + printf("Price: "); scanf("%f", &datap->price); + bytes = fwrite(datap, sizeof(struct myData), 1, fp); + if (bytes != 1) + { + fprintf(stderr, "Could not write to the file!\n"); + return 1; + } + } +} + +void printUsage(char *arg) +{ + fprintf(stderr, "Usage: %s [-l] [-s name]" + "[-m name \n" + "[-d name] [-n] [-h]\n\n" + "-l = list the articles in the database\n" + "-s name = search for an 'name' in the database\n" + "-m name = modify the article named 'name' in the database\n" + " You'll then have the choice to change name, quantity " + "and price.\n" + "-d name = delete the article named 'name'\n" + "-n = create new articles (interactive mode only)\n" + "-h = display this help message\n", arg); +} + +void printHeader(void) +{ + int i; + printf("\n%-30s\t", "Name"); + printf("%s\t", "Quantity"); + printf("%s\t\n", "Price"); + for (i = 0; i<=52; i++) + printf("="); + printf("\n"); +}