Grading Log for CS113 -- HW3 Name: Fried, Limor SCRIPT FILES ====== ===== h3.scr =================================================== > Script started on Thu Mar 04 09:39:53 1999 > % cat *.[ch] /* Add descriptive comments. -TF */ > #include > #include > > #include "h3invent.h" /* holds consts, (proto)types, defs..*/ > > > void InventoryInitialize(inventoryT *listP) > { > listP->howmany = 0; /* well, that was easy */ > } > > int InventoryAddItems(inventoryT *listP, itemT item) > { > int num; > > num = InventoryGetItemNum(listP, item); /* Get the index */ > > if (num == INVENT_NO_SUCH_ITEM) > { > if (listP->howmany == MAX_INVENTORY - 1) /* Check for room */ > return(INVENT_NO_ROOM); > > InventoryCopyItem(&item, &(listP->items[listP->howmany])); > /* Copy the item into the last slot in the inventory */ > > listP->howmany++; > return(item.count); > } > /* else the item exists */ > if (item.price != listP->items[num].price) > return(INVENT_PRICE_MISMATCH); > > listP->items[num].count += item.count; > > return(listP->items[num].count); > } > > > int InventoryGetItemNum(inventoryT *listP, itemT item) > { > int i; > > for(i=0 ; i < listP->howmany ; i++) /* iterate thru the array */ > if (! strcmp(listP->items[i].name, item.name)) /* find a match */ > return(i); > return(INVENT_NO_SUCH_ITEM); /* no match found */ > } > > int InventoryRemoveItems(inventoryT *listP, itemT item) > { > int i, num; > itemT *storeditem; > > if ( (num = InventoryGetItemNum(listP, item)) == INVENT_NO_SUCH_ITEM) > return(num); /* pass the error down */ > > storeditem = &(listP->items[num]); /* cleaner looking code */ > if (storeditem->count > item.count) /* we have some left */ > { > storeditem->count -= item.count; > return(storeditem->count); > } > > if (storeditem->count < item.count) > return(INVENT_NOT_ENOUGH); /* cant have negative inventory */ > > /* else, storeditem->count == item.count */ > > for(i = num; ihowmany; i++) /* Shift the whole list down */ > InventoryCopyItem(&(listP->items[i+1]), &(listP->items[i])); > > listP->howmany--; > > return(0); > } /* * Overkill since structure assignment works just fine, but a * good example of how to isolate an implementation detail (like * the exact fields in the structure) to one function. -TF */ > void InventoryCopyItem(itemT *from, itemT *to) > { > to->count = from->count; > to->price = from->price; > strncpy(to->name, from->name, NAME_MAX+1); > } > > int InventoryGetPrice(inventoryT *listP, itemT item) > { > int num; > > if ( (num = InventoryGetItemNum(listP, item)) == INVENT_NO_SUCH_ITEM) > return(num); > > return(listP->items[num].price); > > } > > int InventorySetPrice(inventoryT *listP, itemT item) > { > int num, oldprice; > > if ( (num = InventoryGetItemNum(listP, item)) == INVENT_NO_SUCH_ITEM) > return(num); > > oldprice = listP->items[num].price; /* save the price, for return */ > listP->items[num].price = item.price; > return(oldprice); > } > > > int InventoryReadFromFile(inventoryT *listP, char filename[]) > { > int num, retval; > FILE *fp; > > char name[NAME_MAX+1]; > int count, price; > itemT item; > > if ( (fp = fopen(filename, "r")) == NULL) > return(INVENT_FILE_ERROR); > num = 0; > > while(fscanf(fp, "%s %d %d", name, &count, &price) != EOF) > { /* go through the entire file */ > if (price<0 || count <0) > continue; > item.count = count; > item.price = price; > strcpy(item.name, name); > > if ( (retval = InventoryAddItems(listP, item)) < 0) /* Good, just reused InventoryAddItems since it's already written. -TF */ > { > if (fclose(fp) != 0) > return(INVENT_FILE_ERROR); > else > return(retval); /* we had an error, bail out */ > } > num++; > } > > if (fclose(fp) != 0) > return(INVENT_FILE_ERROR); /* eek */ > > return(num-1); /* return the number of items we added */ /* Should just be "num". -TF */ > } > > > > > #ifndef _h3invent_h > #define _h3invent_h > > > #define INVENT_NO_ROOM -1 > #define INVENT_NO_SUCH_ITEM -2 > #define INVENT_PRICE_MISMATCH -3 > #define INVENT_NOT_ENOUGH -4 > #define INVENT_FILE_ERROR -5 > > #define MAX_INVENTORY 10 /* * MAX_INVENTORY should be 200, but easier to test limits at 10, * I suppose. -TF */ > #define NAME_MAX 20 > > typedef struct { > char name[NAME_MAX+1]; /* One extra for the '\0' character. */ > int count; /* Number of units in stock. */ > int price; /* Cost of a single unit in cents. */ > } itemT; > > typedef struct { > itemT items[MAX_INVENTORY]; /* Stores all the items. */ > int howmany; /* How many items currently in inventory. */ > } inventoryT; > > void InventoryInitialize(inventoryT *listP); > /* This procedure initializes an inventory variable so that it > * represents an empty inventory. > */ > > int InventoryAddItems(inventoryT *listP, itemT item); > /* Takes an inventory list, adds in item if it doesnt exist and there's enough > * space. If it exists, it adds it in assuming the price is consistant. > */ > > int InventoryRemoveItems(inventoryT *listP, itemT item); > /* Removes a a given number of 'item' from the inventory, cleans up if the > * count is 0 > */ > > int InventoryGetPrice(inventoryT *listP, itemT item); > /* Retrieves the price for the given item */ > > int InventorySetPrice(inventoryT *listP, itemT item); > /* Sets the price for the given item, returns the old price */ > > int InventoryReadFromFile(inventoryT *listP, char filename[]); > /* Reads in an inventory from a given file, and stores it in the list. */ > > void InventoryCopyItem(itemT *from, itemT *to); > /* A little 'convenience' function which dups an item */ > > int InventoryGetItemNum(inventoryT *, itemT); > /* finds the index of the item in the inventory, or returns <0 */ > > > > #endif /* _h3invent_h */ > > > #include > #include > #include "h3invent.h" > > #define INVENTORYFILE "/cs/course/cs113/current/hw3/inventory.dat" > > /********************* PROTOTYPES ****************************/ > void PrintMenu(void); > /* prints out the intro menu */ > > void Quit(void); > /* Quits */ > > void ChangeItem(inventoryT *); > /* Handles the input/output of changing the price of items */ > > void AddItems(inventoryT *); > /* Handles the input/output of adding items */ > > void RemItems(inventoryT *); > /* Handles the input/output of removing items */ > > void PriceItem(inventoryT *); > /* Handles the input/output of pricing items */ > > void FillItem(itemT *, char *, int, int); > /* A little 'convenience' function which fills out an item */ > > > void PriceToStr(int c, char str[15]); > /* converts an int number of pennies into the appropriate $ string */ > > > /************************ MAIN ***************************/ > int main(void) > { > inventoryT Inventory; > int i; > char choice; > char tmp[80]; > > InventoryInitialize(&Inventory); > > /* read in the file, handle the errors */ > > i = InventoryReadFromFile(&Inventory, INVENTORYFILE); > if (i == INVENT_FILE_ERROR) > printf("Had problems opening/reading %s.\n", INVENTORYFILE); > else if (i == INVENT_NO_ROOM) > printf("Tried to read in too many items.\n"); > else if (i == INVENT_PRICE_MISMATCH) > printf("Inventory file had a price mismatch.\n"); > else > printf("Read in %d items from %s.\n", i, INVENTORYFILE); > > PrintMenu(); > > while (1) { > printf("Choice> "); > scanf("%s", tmp); /* to avoid whitespace issues */ > choice = tmp[0]; > > switch(choice) > { > case 'a': AddItems(&Inventory); break; > case 'r': RemItems(&Inventory); break; > case 'p': PriceItem(&Inventory); break; > case 'c': ChangeItem(&Inventory); break; > case 'h': PrintMenu(); break; > case 'q': Quit(); > } > } > return(0); > } > > /***************** I/O FUNCTIONS ****************************/ > > void AddItems(inventoryT *listP) > { > char name[NAME_MAX+1]; > int num, price, i; > itemT item; > num=price=0; > > printf("Item name: "); > scanf("%s", name); > > while(1) { > printf("Add quantity: "); > scanf("%d", &num); > if (num>0) > break; > printf("Quantity must be positive\n"); > } > > while(1) { > printf("Unit price, in cents: "); > scanf("%d", &price); > if (price>0) > break; > printf("Price must be positive\n"); > } > > FillItem(&item, name, num, price); > i = InventoryAddItems(listP, item); > if (i == INVENT_NO_ROOM) > printf("Inventory was not large enough to add in the new item.\n"); > else if (i == INVENT_PRICE_MISMATCH) > printf("There was a price mismatch. Try again.\n"); > else > printf("There are now %d units of \"%s\"\n", i, name); > } > > void RemItems(inventoryT *listP) > { > char name[NAME_MAX+1]; > int num; > itemT item; > > printf("What item to remove: "); > scanf("%s", name); > while(1) { > printf("How many to remove: "); > scanf("%d", &num); > if (num>0) > break; > printf("Number to remove must be positive.\n"); > } > FillItem(&item, name, num, 0); > num = InventoryRemoveItems(listP, item); > if (num == INVENT_NO_SUCH_ITEM) > printf("The item \"%s\" does not exist!\n", name); > else if (num == INVENT_NOT_ENOUGH) > printf("Can't remove that many!\n"); > else > printf("%d of \"%s\" remain.\n", num, name); > } > > void PriceItem(inventoryT *listP) > { > char name[NAME_MAX+1]; > int price; > itemT item; > char pricestr[15]; > > printf("Item name: "); > scanf("%s", name); > FillItem(&item, name, 0, 0); > > price = InventoryGetPrice(listP, item); > PriceToStr(price, pricestr); > > if (price == INVENT_NO_SUCH_ITEM) > printf("The item \"%s\" doenst exist!\n", name); > else > printf("The price for a unit of \"%s\" is %s\n", name, pricestr); > } > > void ChangeItem(inventoryT *listP) > { > char name[NAME_MAX+1], pricestr[15]; > int price, oldprice; > itemT item; > > printf("\nItem name: "); > scanf("%s", name); > while(1) { > printf("New unit price (in cents): "); > scanf("%d", &price); > if (price>0) > break; > printf("Price must be positive.\n"); > } > FillItem(&item, name, 0, price); > > if ( (oldprice = InventorySetPrice(listP, item)) == INVENT_NO_SUCH_ITEM) > { > printf("No such item \"%s\" in the inventory!\n", name); > return; > } > PriceToStr((price - oldprice), pricestr); > printf("Price of \"%s\" changed by %s\n", name, pricestr); > return; > } > > void Quit(void) > { > printf("Bye! Thanks for using inventory.\n"); > exit(0); > } > > void PrintMenu(void) > { > printf("Please choose one of the following operations by typing its letter and then pressing :\n\n"); > printf(" a) Add some items.\n"); > printf(" r) Remove (sell) some items.\n"); > printf(" p) Show the price for an item.\n"); > printf(" c) change the price of an item.\n"); > printf(" q) Quit inventory.\n\n"); > } > > > void PriceToStr(int c, char str[15]) > { > char tmp[13]; > int t; > > if (c<0) > { > c = -c; > str[0] = '-'; str[1] = '$'; str[2] = 0; > } else { > str[0] = '$'; str[1] = 0; > } > t = c%100; > if (t < 10) > sprintf(tmp, "%d.0%d", c/100, t); > else > sprintf(tmp, "%d.%d", c/100, t); > > strncat(str, tmp, 12); > } > > > void FillItem(itemT *i, char *n, int count, int price) > { > strncpy(i->name, n, NAME_MAX); > i->count = count; > i->price = price; > } > > > > % make > gcc -ansi -pedantic -Wall -g -c h3main.c > gcc -ansi -pedantic -Wall -g -c h3invent.c > gcc -ansi -pedantic -Wall -g -o h3inventory h3main.o h3invent.o > % ./h3inventory > Read in 8 items from /cs/course/cs113/current/hw3/inventory.dat. ^^ 9 technically > Please choose one of the following operations by typing its letter and then pressing : > > a) Add some items. > r) Remove (sell) some items. > p) Show the price for an item. > c) change the price of an item. > q) Quit inventory. > > Choice> a > Item name: Twizzlers > Add quantity: 10 > Unit price, in cents: 99 > Inventory was not large enough to add in the new item. > Choice> p > Item name: Rice_chex > The price for a unit of "Rice_chex" is $1.99 > Choice> r > What item to remove: Rice_chex 0 > How many to remove: Number to remove must be positive. > How many to remove: 1 > 98 of "Rice_chex" remain. > Choice> r > What item to remove: Rice_chex > How many to remove: 99 > Can't remove that many! > Choice> r > What item to remove: Rice_chex > How many to remove: 98 > 0 of "Rice_chex" remain. > Choice> p > Item name: Rice_chex > The item "Rice_chex" doenst exist! > Choice> a > Item name: Twizzlers > Add quantity: 90 > Unit price, in cents: 99 > There are now 90 units of "Twizzlers" > Choice> c > > Item name: Twizzlers > New unit price (in cents): 100 > Price of "Twizzlers" changed by $0.01 > Choice> c > > Item name: Cheerios > New unit price (in cents): -99 > Price must be positive. > New unit price (in cents): 100 > Price of "Cheerios" changed by -$2.95 > Choice> a > Item name: Cheerios > Add quantity: -10 > Quantity must be positive > Add quantity: 10 > Unit price, in cents: 99 > There was a price mismatch. Try again. > Choice> p > Item name: Cheerios > The price for a unit of "Cheerios" is $1.00 > Choice> a > Item name: Cheerios > Add quantity: 10 > Unit price, in cents: 100 > There are now 34 units of "Cheerios" > Choice> r > What item to remove: Cheerios > How many to remove: 34 > 0 of "Cheerios" remain. > Choice> a > Item name: Twix > Add quantity: 0 > Quantity must be positive > Add quantity: 13 > Unit price, in cents: 1 > There are now 13 units of "Twix" > Choice> a > Item name: Boom > Add quantity: 10 > Unit price, in cents: 1111 > Inventory was not large enough to add in the new item. > Choice> q > Bye! Thanks for using inventory. > % exit > exit > > script done on Thu Mar 04 09:43:28 1999