COMP1721 - Higher Computing 1B

Computing 1B - Week 12 Tutorial Solutions

  1. #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct purchase purchase;
    typedef struct item     item;
    typedef double          price;
    typedef long            barcode;
    
    struct purchase {
        item        *what;
        int         how_many;
        purchase    *next;
    };
    
    struct item {
        char    *item_name;
        price   item_price;
        barcode item_barcode;
        item    *next;
    };
    
    enum {
        MAX_INPUT_LINE_LENGTH = 1024
    };
    
    void print_bill(purchase *purchase_list);
    purchase *add_purchase(barcode code, purchase *purchase_list, item *item_list);
    purchase *find_purchase(item *i, purchase *purchase_list);
    item *add_item(item *item_list);
    item *find_item(barcode code, item *item_list);
    void *salloc(size_t size);
    void read_to_newline(void);
    
    int
    main(void) {
        char command[MAX_INPUT_LINE_LENGTH];
        purchase *purchase_list = NULL;
        item *item_list = NULL;
        
        printf("Kensington Kwiki-Mart Billing System\n");
        while (1) {
            printf("Enter Command: ");
            if (fgets(command, MAX_INPUT_LINE_LENGTH, stdin) == NULL)
                return 0;
            
            if (strcmp(command,"bill\n") == 0) {
                while (1) {
                    barcode code;
                    printf("Enter barcode: ");
                    scanf("%ld", &code);
                    read_to_newline();
                    if (code == 0)
                        break;
                    purchase_list = add_purchase(code, purchase_list, item_list);
                }
              print_bill(purchase_list);
            } else if (strcmp(command, "price\n") == 0) {
                item_list = add_item(item_list);
            } else {
                printf("Unknown command - legal commands are bill and price\n");
            }
        }
        return 0;
    }
    
    void
    print_bill(purchase *purchase_list) {
        price total = 0;
        purchase *p;
        
        for (p = purchase_list; p != NULL; p = p->next) {
            price x = p->how_many * p->what->item_price;
            total += x;
            printf("%dx %s @$%.2f = $%.2f\n", p->how_many, p->what->item_name, p->what->item_price, x);
        }
    
        printf("Total: $%.2f\n", total);
        printf("Thank for Shopping at Kensington Kwiki-Mart\n");
    }
    
    
    purchase *
    add_purchase(barcode  code, purchase *purchase_list, item *item_list) {
        purchase *p;
        item     *i;
        
        i = find_item(code, item_list);
        if (i == NULL) {
            fprintf(stderr, "Unknown barcode\n");
            return purchase_list;
        }
        
        p = find_purchase(i, purchase_list);
        
        if (p != NULL) {
            p->how_many++;
            return purchase_list;
        }
        
        p = salloc(sizeof (purchase));
        p->what = i;
        p->how_many = 1;
        p->next = purchase_list;
        return p;
    }
    
    purchase *
    find_purchase(item *i, purchase *purchase_list) {
        purchase *p;
        
        for (p = purchase_list; p != NULL; p = p->next)
            if (p->what == i)
                return p;
        
        return NULL;
    }
    
    item *
    add_item(item *item_list) {
        barcode code;
        char    buffer[MAX_INPUT_LINE_LENGTH];
        item    *i;
        
        printf("Enter barcode: ");
        scanf("%ld", &code);
        read_to_newline();
        i = find_item(code, item_list);
    
        if (i != NULL) {
            printf("Enter new price for %s: ", i->item_name);
            scanf("%lf", &(i->item_price));
            read_to_newline();
            return item_list;
        }
        
        i = salloc(sizeof (item));
        i->item_barcode = code;
        printf("Enter name of the item: ");
        if (fgets(buffer, MAX_INPUT_LINE_LENGTH, stdin) == NULL || strlen(buffer) == 0) {
            fprintf(stderr, "Can not read name\n");
            exit(1);
        }
        buffer[strlen(buffer) - 1] = '\0'; /* remove '\n' */
        i->item_name = salloc(strlen(buffer) + 1);
        strcpy(i->item_name, buffer);
        printf("Enter price: ");
        scanf("%lf", &(i->item_price));
        read_to_newline();
        i->next = item_list;
        return i;
    }
        
    item *
    find_item(barcode code, item *item_list) {
        item *i;
        for (i = item_list; i != NULL; i = i->next) {
            if (i->item_barcode == code)
                return i;
        }
        return NULL;
    }
    
    void *
    salloc(size_t size) {
        void *m = malloc(size);
        if (m == NULL) {
            fprintf(stderr, "postcode_server: out of memory - attempting to malloc %d bytes\n", (int)size);
            exit(1);
        }
        return m;
    }
    
    void
    read_to_newline(void) {
        int c;
        while (1) {
            c = getchar();
            if (c == '\n' || c == EOF)
                return;
        }
    }
    


Andrew Taylor (andrewt@cse.unsw.edu.au)
Higher Computing 1B, Computer Science & Engineering, UNSW