#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;
}
}