In: Computer Science
(Linked Lists)
The Problem
UCF is growing so large that they’re actually starting a mini-supermarket, KnightsMart, stocked with typical supermarket products along with all the studying essentials (selection of coffees and creamers, pallets upon pallets of Red Bull, and all the Twinkies you can imagine!).
KnightsMart is in need of a program that:
Throughout any given day, the following things can occur (just as in a normal store):
For this program, you will need to maintain three linked lists: a linked list of all products in the store, a linked list of products that need to be reordered, and a linked list of sales that occur on any given day.
You will read in a list of commands from an input file, and your program will execute those commands accordingly. The final command, for each day, will be one that prints out a summary for all sales in the given day, which is detailed in the input/output specifications.
Implementation
You will need to make use of the following structures (EXACTLY as shown):
typedef struct KnightsMartProduct {
int itemNum; char itemName[21]; double unitPrice; int stockQty; int restockQty;
struct KnightsMartProduct *next;
} KMProduct;
typedef struct KnightsMartRestockProduct {
int itemNum;
struct KnightsMartRestockProduct *next;
} KMRestockProduct;
typedef struct KnightsMartSale { char firstName[21];
char lastName[21];
int numItemsOnList; // # of items on shopping list int *itemsPurchased; // array of item numbers
struct KnightsMartSale *next; } KMSale;
You will need to make the following three linked lists:
KMRestockProduct node is made, and it is immediately added to the end of this list.
Input File Specifications
You will read in input from a file, "KnightsMart.in". Have this AUTOMATED. Do not ask the user to enter “KnightsMart.in”. You should read in this automatically. (This will expedite the grading process.). The first line of the file will be an integer, d, representing the number of days that the simulation will run. The first line of each simulation will be an integer, k, indicating the number of commands that will be run for that day’s simulation, with each command occurring on a separate line. Each of those k commands will be followed by relevant data as described below (and this relevant data will be on the same line as the command).
The commands you will have to implement are as follows:
◦ You need to traverse the list using the method shown in class.
◦ For every product (node) in this KMRestockList list, you need to search for that item in the KMproducts list, which will allow you to restock that node accordingly.
◦ Once found, you will increase the stockQty member of that KMProduct based on the restockQty member of that same KMProduct.
◦ You then need to delete that particular product (node) from the KMRestockList. Note: since you delete from the KMRestockList as you traverse the list, this means that you will simply be deleting from the front of the list at all times. ◦ Assuming you follow these steps properly, once you’ve traversed the entire
KMRestockList, restocked all necessary products, and then deleted those products from the KMRestockList, at this point KMRestockList will have no nodes and should point to NULL (meaning, the list is empty).
As mentioned previously, a purchase occurs when a customer finds, and of course then buys, one of the items on their shopping list. When this happens, a KMSale node must be made, which records this sale. The struct members must then be filled in accordingly. One member of the KMSale node is itemsPurchased. This is an array that must be dynamically allocated based on the size (number) on the original shopping list. If the product is found and purchased, the item number is added to the corresponding cell of this array, along with the quantity purchased. We assume that if the stock for a given item is available, the customer will purchase the full desired quantity on their shopping list (of that item). If the product is not found, a zero is recorded in that cell of the array. Based on the three-item example above, if the first and third items were available, with the second being unavailable (no stock), the itemsPurchased array would have SIX cells as follows: 5437, 2, 8126, 0, 9828, 4. This shows that 2 units of 5437 were purchased, and 4 units of 9828 were purchased; the zero after item 8126 simply shows that the item was not available. Finally, once all appropriate information is saved into the struct members of the KMSale node, this node is then added to the end of the KMSales list. Note: a line of output is printed regardless of whether or not a purchase was made. Refer to sample output for examples.
◦ You need to traverse the list using the method shown in class.
◦ For every Sale (node) in the KMSales list, you need to print Sale number (starting at 1), along with the first and last name of the customer (in that order). You then need to print the list of items that were successfully found and then purchased. Finally, you need to print the total amount paid. Please refer to the EXACT output format for specifics.
◦ After printing the appropriate information, you then need to delete that particular Sale (node) from the KMSales list. Note: since you delete from the KMSales list as you traverse the list, this means that you will simply be deleting from the front of the list at all times. This also means that the first Sale (node) in the list will be both the first Sale printed and the first Sale deleted.
◦ Assuming you follow these steps properly, once you’ve traversed the entire KMSales list, printed all necessary information, and then deleted those Sales from the KMSales list, at this point the KMSales list will have no nodes and should point to NULL (meaning, the list is empty).
◦ Lastly, you must print out the total sales (dollar amount) for the given day.
Status of Lists at the end of each day:
At the end of each day, the KMSales list will clearly be empty, as per the description in the PRINTDAYSUMMARY command. This prints each Sale, deletes each node, effectively destroying that list. The other two lists, KMProducts and KMRestockList, will be maintained throughout the entire running of your program. Meaning, you clearly should not destroy (delete all nodes from) the list of products in the store at the end of a day, as this would result in there being no products in the store for subsequent days. Additionally, the
KMRestockList will also be maintained over the simulation. This means that if there were items in the KMRestockList at the end of a given day, those items will remain in that list at the beginning of the next day, thereby allowing them to be restocked whenever a REORDER command arrives.
Output Format
Your program must output to a file, called "KnightsMart.out". You must follow the program specifications exactly. You will lose points for formatting errors and spelling.
When examining the output file, you should notice that the INVENTORY command and the PRINTDAYSUMMARY command results in printing a “semi-formatted” line of text. To avoid guessing games and to guarantee the correctness of your format, we are providing those two print literals below:
Here is the literal for printing inventory items in the INVENTORY command:
"\t| Item %6d | %-20s | $%7.2lf | %4d unit(s) |\n"
And here is the literal for printing customer items in the PRINTDAYSUMMARY command:
"\t\t| Item %6d | %-20s | $%7.2lf (x%4d) |\n"
Answer:
Program code to copy:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// define the macros to test the null pointer for the pointers
created and
// for the file pointers
#define checkNullPointer( pointer ) \
if( pointer == NULL ) \
{ \
printf("\n\nFailure allocating
memory! "); \
printf("Check line %d! Terminating
Program!\n", __LINE__); \
exit(EXIT_FAILURE); \
}\
#define checkFilePointer( pointer )if( pointer == NULL ) {
printf("\n\nFile not found! Check line %d! Terminating Program!\n",
__LINE__); exit(EXIT_FAILURE); }
// Structure to hold the Knights Mart Product information
typedef struct KnightsMartProduct
{
int
itemNum;
char
itemName[21];
double unitPrice;
int
stockQty;
int
restockQty;
struct KnightsMartProduct *next;
} KMProduct;
// Structure to hold the Knights Mart Restock Product
information
typedef struct KnightsMartRestockProduct
{
int
itemNum;
struct KnightsMartRestockProduct *next;
} KMRestockProduct;
// Structure to hold the Knights Mart Product information
typedef struct KnightsMartSale
{
char
firstName[21];
char
lastName[21];
int
*itemsPurchased;
int
numItems;
struct KnightsMartSale *next;
} KMSale;
// addInventoryItems - function accepts a KMProduct pointer,
with list
// of items that need to be stored and File output pointer.
// This function returns the updated inventory list and at the same
time
// writes the inverntory information to the output file.
KMProduct *addInventoryItems(KMProduct *kmproductList, int itemNum,
char *itemName,
double unitPrice, int stockQty, int restockQty, FILE
*fileOut);
// inventoryRestock - This function updates the inventory
product list pointer
// with the list of restock and at the same time tries to remove
list information of
// restock.
// This function returns the updated restock product list and
writes the information
// to the output file.
KMRestockProduct *inventoryRestock(KMProduct *kmproductList,
KMRestockProduct *kmrestockList,
FILE *fileOut);
// customerInfo - This function tries to gathers customer data
and subsequently
// updates the three Kight Mart list information and prints the the
data to the output
// file.
void customerInfo(KMProduct *kmproductList,
KMRestockProduct **kmrestockList,
KMSale **kmsaleList, char *firstName, char
*lastName,
int numItems, int *items, FILE
*fileOut);
// inventoryInfo - This function prints the information of the
product list to
// the output file.
void inventoryInfo(KMProduct *kmproductList, FILE *fileOut);
// displaySummaryPerDay - This function displays the summary
report that has taken
// place in a day by using the kmproductList and kmsalesList to the
output file.
// And also, it clears the information of the kmsalesList.
KMSale *displaySummaryPerDay(KMProduct
*kmproductList, KMSale *kmsaleList, FILE
*fileOut);
// function to destroy the kmproductList
KMProduct *clearKMProduct(KMProduct *kmproductList);
// functions to destroy the kmsaleList
KMRestockProduct *clearKMRestockProduct(KMRestockProduct
*kmsaleList);
// functions to destroy the kmsaleList
KMSale *clearKMSale(KMSale *kmsaleList);
int main()
{
// Define the pointers to the three linked lists as
headers.
// One pointer to maintain the KMProduct list.
KMProduct *prod_Invent_List = NULL;
// Second pointer to maintain the KMRestockProduct
list
KMRestockProduct *restock_Invent_List = NULL;
// Third pointer to maintain the KMSale list
KMSale *km_SaleList = NULL;
// delcare the required iterative or helper
variables
int i, j, k;
// declare the variables to hold the number
of
// days and total commands
// variable to hold the number of days
unsigned long num_Of_Days;
// variable to hold total number of commands are
executed
// per day
unsigned long num_Commands_Per_Day;
// variable to hold the command read from the
file.
char commandToProcess[100];
// define a file pointer to point to the input
file
// named KnightsMart.in
FILE *fileIn = fopen("KnightsMart.in", "r");
// check for the error information
checkFilePointer(fileIn);
// define a file pointer to point to the output
file
// named KnightsMart.out
FILE *fileOut = fopen("KnightsMart.out", "w");
// check for the error information
checkFilePointer(fileOut);
// after opening the file, read the number of days
from
// the input file
fscanf(fileIn, "%lu", &num_Of_Days);
// loop to process the inventory, customer and
stock information
// for each day.
for (i = 0; i < num_Of_Days; i++)
{
// Display the header to the output
file
fprintf(fileOut,
"*************************\n");
fprintf(fileOut, "UCF KnightsMart
Day %d\n");
fprintf(fileOut,
"*************************\n", i + 1);
// read number of commands
processed per day
fscanf(fileIn, "%lu",
&num_Commands_Per_Day);
// loop through each command
executed per day
for (j = 0; j <
num_Commands_Per_Day; j++)
{
// Read the
command from the file
fscanf(fileIn,
"%s", commandToProcess);
// Check
whether the commandToProcess is ADDITEM.
// If so, read
the information into inventory
if
(!strcmp(commandToProcess, "ADDITEM"))
{
// Declare the required variables to hold
the
// inputs read from the file
int itemNum;
char itemName[21];
double unitPrice;
int stockQty;
int restockQty;
// read the item information from the file
fscanf(fileIn, "%d%s%lf%d%d", &itemNum,
itemName, &unitPrice,
&stockQty, &restockQty);
// add the item information to the product's
inventory list
prod_Invent_List =
addInventoryItems(prod_Invent_List, itemNum, itemName,
unitPrice, stockQty, restockQty, fileOut);
}
// Check
whether the commandToProcess is RESTOCK.
// If so,
process the restock list and write the information
// to the output
file
else if
(!strcmp(commandToProcess, "RESTOCK"))
{
restock_Invent_List =
inventoryRestock(prod_Invent_List, restock_Invent_List,
fileOut);
}
// Check
whether the commandToProcess is CUSTOMER.
// If so,
process the customer information and customer's product's
information
// list and
write the information
// to the output
file
else if
(!strcmp(commandToProcess, "CUSTOMER"))
{
// Declare the required variables to hold
the
// inputs read from the file
char firstName[21];
char lastName[21];
int numItems;
int *items;
// Read the customer information from the
file
fscanf(fileIn, "%s%s%d", firstName, lastName,
&numItems);
// initialize the items array with numItems
space memory
items = malloc(numItems * sizeof(int));
// read the customer items from the file
for (k = 0; k < (numItems); k++)
{
fscanf(fileIn, "%d",
&items[k]);
}
customerInfo(prod_Invent_List,
&restock_Invent_List, &km_SaleList,
firstName, lastName, numItems, items, fileOut);
}
// Check
whether the commandToProcess is INVENTORY.
// If so,
display the information of products list
// to output
file
else if
(!strcmp(commandToProcess, "INVENTORY"))
{
inventoryInfo(prod_Invent_List, fileOut);
}
// Check
whether the commandToProcess is PRINTDAYSUMMARY.
// If so,
display the products and sales information to the
// output
file
else if
(!strcmp(commandToProcess, "PRINTDAYSUMMARY"))
{
km_SaleList =
displaySummaryPerDay(prod_Invent_List, km_SaleList, fileOut);
}
}
fprintf(fileOut, "\n");
}
// Call functions to free memory for all linked
lists.
prod_Invent_List =
clearKMProduct(prod_Invent_List);
restock_Invent_List =
clearKMRestockProduct(restock_Invent_List);
km_SaleList = clearKMSale(km_SaleList);
// to halt the screen
getchar();
getchar();
exit(EXIT_SUCCESS);
}
// function accepts a KMProduct pointer, with list
// of items that need to be stored and File output pointer.
// This function returns the updated inventory list and at the same
time
// writes the inverntory information to the output file.
KMProduct *addInventoryItems(KMProduct *kmproductList, int
itemNum,
char *itemName, double unitPrice, int
stockQty,
int restockQty, FILE *fileOut)
{
// initialize the kmprodPtr with the
kmproductList
KMProduct *kmprodPtr = kmproductList;
// Create a new node and allocate memory
KMProduct *addProdNode =
malloc(sizeof(KMProduct));
// check for the pointer exception
checkNullPointer(addProdNode);
// set the node values with parameter values
addProdNode->itemNum = itemNum;
strcpy(addProdNode->itemName, itemName);
addProdNode->unitPrice = unitPrice;
addProdNode->stockQty = stockQty;
addProdNode->restockQty = restockQty;
// Display the items information to the output
file
fprintf(fileOut, "Item %d, %s, with a cost of $%3.2lf
and initial stock of %d,"
" has been
added to the product database.\n", itemNum, itemName,
unitPrice, stockQty);
// If kmproPtr pointer is null,
// then add the next pointer of addProdList
// This is first node in the product list
if (kmprodPtr == NULL)
{
addProdNode->next = NULL;
return addProdNode;
}
// Condition to check whether the itemNum is less
than
// current kmprodPtr itemNum.
// If the condition is satisfied, then add the
new
// added item to the front of the kmprodPtr
if (itemNum < kmprodPtr->itemNum)
{
addProdNode->next =
kmprodPtr;
return addProdNode;
}
// If above two condition fails, then proceed to
add
// the product to the list. So, define the
pointer
// by initializing with kmprodPtr's next pointer
value
KMProduct *tempPtr = kmprodPtr->next;
// loop(traverse) through each value in the tempPtr
list
while (tempPtr != NULL)
{
// Check the condition wether the
itemNum is less than the
// tempPtr's itemNum
if (itemNum <
tempPtr->itemNum)
{
// set the
tempPtr to addProdList
addProdNode->next = tempPtr;
// set the
addProdList pointer to
// kmprodPtr
next value
kmprodPtr->next = addProdNode;
// break the
loop
break;
}
// if not, move the
pointer
kmprodPtr =
kmprodPtr->next;
tempPtr = tempPtr->next;
}
// if the tempPtr is null
if (tempPtr == NULL)
{
// set the next pointer of
addProdNode to null
// indicating the last node
addProdNode->next = NULL;
// update the kmprodPtr to the new
previous node
kmprodPtr->next =
addProdNode;
}
// returnt the updated kmproductList
return kmproductList;
}
// This function updates the inventory product list
pointer
// with the list of restock and at the same time tries to remove
list information of
// restock.
// This function returns the updated restock product list and
writes the information
// to the output file.
KMRestockProduct *inventoryRestock(KMProduct *kmproductList,
KMRestockProduct *kmrestockList,
FILE *fileOut)
{
// Set the kmrestockList pointer to the
restockPter.
KMRestockProduct *restockPtr = kmrestockList;
// Condition to check whether the restockPtr list
is empty
// or not
if (restockPtr == NULL)
{
// If so, display the information
to the output file
fprintf(fileOut, "RESTOCK: the
Restock List contains no items.\n");
// return the
kmrestockList
return kmrestockList;
}
// if the above condition fails, then write the
restock infomration
// to the output file
fprintf(fileOut, "RESTOCK: the following items have
been reordered and restocked:\n");
// declare a pointer of type KMProduct
KMProduct *prod_Temp_Ptr;
// declare the temp pointer for the
KMRestockProduct
KMRestockProduct *tempKMR;
// process through each node of the restockPtr
list
while (restockPtr != NULL)
{
// set the kmprodeList to
prod_Temp_Ptr
prod_Temp_Ptr = kmproductList;
// loop through each node of the
prod_Temp_Ptr list
while (prod_Temp_Ptr != NULL)
{
// check wether
the itemNum of the product list and
// restock are
same or not
if
(prod_Temp_Ptr->itemNum == restockPtr->itemNum)
{
// if so, display the information of the item
restock
fprintf(fileOut, "\tItem %d, %s, restocked to a
quantity of %d.\n",
prod_Temp_Ptr->itemNum, prod_Temp_Ptr->itemName,
prod_Temp_Ptr->restockQty);
// Set restock quantity of product to stockQty
of product
prod_Temp_Ptr->stockQty =
prod_Temp_Ptr->restockQty;
break;
}
// move the
pointer to next node
prod_Temp_Ptr =
prod_Temp_Ptr->next;
}
// update the tempKMR
tempKMR = restockPtr;
// set the current pointer of
restockPtr to restock list
restockPtr =
restockPtr->next;
// delete the tempKMR
pointer
free(tempKMR);
}
// Return NULL inorder to set the restocklinked
list to empty.
return NULL;
}
// This function tries to gathers customer data and
subsequently
// updates the three Kight Mart list information and prints the the
data to the output
// file.
void customerInfo(KMProduct *kmproductList,
KMRestockProduct **kmrestockList,
KMSale **kmsaleList, char *firstName, char
*lastName, int numItems,
int *items, FILE *fileOut)
{
// declare a pointer of type KMProduct
KMProduct *prod_temp_Ptr;
// Set the temp of the restock with restock
list
KMRestockProduct *restock_Temp_Ptr =
(*kmrestockList);
// declare a pointer of type KMSale
KMSale *sale_temp_Ptr;
// declare the flag variable
int flag_saleMade = 0;
// if the restock list is not empty
if (restock_Temp_Ptr != NULL)
{
// traverse through the restock
list
while (restock_Temp_Ptr->next !=
NULL)
{
restock_Temp_Ptr
= restock_Temp_Ptr->next;
}
}
// declare an iterative variable
int i;
// loop through each item
for (i = 0; i < (numItems); i += 2)
{
// set the product list to temp
pointer of KMProduct
prod_temp_Ptr = kmproductList;
// loop through each node in the
KMProduct list
while (prod_temp_Ptr != NULL)
{
// check for the
item number in the array of items
if
(prod_temp_Ptr->itemNum == items[i])
{
// If item is available, then check for the
quantity of
// stock in the KMProduct list
if (prod_temp_Ptr->stockQty != 0)
{
// if the stock quantity is
not 0, then check whether
// stock quantity is less
than the next items
if
(prod_temp_Ptr->stockQty < items[i + 1])
{
// set the
stock quantity of KMProduct
// to
items next value
items[i +
1] = prod_temp_Ptr->stockQty;
// set the
stock quantity is zero
prod_temp_Ptr->stockQty = 0;
}
// otherwise, decrement the
stock quantity with the
// items present at i+1
else
{
prod_temp_Ptr->stockQty -= items[i + 1];
}
// set the flag to 1
flag_saleMade = 1;
// If the item stock is
zero
// add the stock to the
list
if
(prod_temp_Ptr->stockQty == 0)
{
// Check
wether the restock temp pointer is empty or not
if
(restock_Temp_Ptr == NULL)
{
// if empty allocate memory to the restock
KMRestock List
(*kmrestockList) =
malloc(sizeof(KMRestockProduct));
checkNullPointer(*kmrestockList);
// set the items at i as itemNum of the
kmrestockList
(*kmrestockList)->itemNum = items[i];
// set the restock list pointer to null
(*kmrestockList)->next = NULL;
restock_Temp_Ptr = (*kmrestockList);
}
// if
restock is not empty add the restock informatin to the
// end of
the list
else
{
restock_Temp_Ptr->next =
malloc(sizeof(KMRestockProduct));
checkNullPointer(restock_Temp_Ptr->next);
restock_Temp_Ptr->next->itemNum =
items[i];
restock_Temp_Ptr->next->next = NULL;
restock_Temp_Ptr =
restock_Temp_Ptr->next;
}
}
}
// set the index of items at i to zero, since
the item is found
// but not in the restock
else
{
items[i] = 0;
}
// break the loop since the product is found in
the list
break;
}
prod_temp_Ptr =
prod_temp_Ptr->next;
}
// If the item is not found then
set the item number in the array at index i to 0
if (prod_temp_Ptr == NULL)
{
items[i] =
0;
}
}
// if the flag is set
if (flag_saleMade == 1)
{
// create the memory for
KMSale
KMSale *saleTempNode =
malloc(sizeof(KMSale));
// set the values to the
strcpy(saleTempNode->firstName,
firstName);
strcpy(saleTempNode->lastName,
lastName);
saleTempNode->itemsPurchased =
items;
saleTempNode->numItems =
numItems;
saleTempNode->next = NULL;
// Set sale_temp_Ptr point to
the kmsaleList.
sale_temp_Ptr = *kmsaleList;
// sale_temp_Ptr list is
empty
if (sale_temp_Ptr == NULL)
{
// Then set the
sale's temp node to list
(*kmsaleList) =
saleTempNode;
}
// otherwise insert the node to the
end of the sales_Temp_Ptr list
else
{
// traverse
through the sale_temp_Ptr list
while
(sale_temp_Ptr->next != NULL)
{
sale_temp_Ptr = sale_temp_Ptr->next;
}
// set the
saleTempNode(new node) to the end of the list
sale_temp_Ptr->next = saleTempNode;
}
// display the information to
the file
fprintf(fileOut, "Customer %s %s
came and made some purchases.\n", firstName, lastName);
}
// If a sale was not made, destroy the items
array.
else
{
fprintf(fileOut, "Customer %s %s
came and made no purchases.\n", firstName, lastName);
// delete the memory allocated
to the items.
free(items);
}
return;
}
// This function prints the information of the product list
to
// the output file.
void inventoryInfo(KMProduct *kmproductList, FILE *fileOut)
{
// Helper pointer to traverse through product linked
list.
KMProduct *prod_temp_Ptr = kmproductList;
// Empty list, print that there is no
inverntory.
if (prod_temp_Ptr == NULL)
{
fprintf(fileOut, "INVENTORY:
contains no items.\n");
return;
}
// display the inventory information
fprintf(fileOut, "INVENTORY: contains the following
items:\n");
// display the product information of each node of
the product list
while (prod_temp_Ptr != NULL)
{
fprintf(fileOut, "\t| Item %6d |
%-20s | $%7.2lf | %4d unit(s) |\n",
prod_temp_Ptr->itemNum,
prod_temp_Ptr->itemName, prod_temp_Ptr->unitPrice,
prod_temp_Ptr->stockQty);
prod_temp_Ptr =
prod_temp_Ptr->next;
}
return;
}
// This function displays the summary report that has
taken
// place in a day by using the kmproductList and kmsalesList to the
output file.
// And also, it clears the information of the kmsalesList.
KMSale *displaySummaryPerDay(KMProduct *kmproductList,
KMSale *kmsaleList, FILE *fileOut)
{
// temperory pointer to traverse through the sales
list
KMSale *sale_temp_Ptr = kmsaleList, *temp_KMS;
// declare the pointer of KMProduct
// to access the kmproductList
KMProduct *prod_temp_Ptr;
// set the counter variable to 1 which holds the
sales number
unsigned long salesCounter = 1;
// define a variable to hold the total cost of the
items
double totalCost = 0;
// declare the iterative variable
int i;
// if the sales list is empty then display that there
is not information about the
// sales
if (sale_temp_Ptr == NULL)
{
fprintf(fileOut, "KnightsMart Daily
Sales report:\n");
fprintf(fileOut, "\tThere were no
sales today.\n");
return kmsaleList;
}
// display the sales report heading
fprintf(fileOut, "KnightsMart Daily Sales
report:\n");
// traverse through the sales list
while (sale_temp_Ptr != NULL)
{
// define a variable to hold the
sub-total of the sales
double sub_total = 0;
// count variable to hold the
customer items count
int cust_items_count = 0;
// loop through the sales list to
find how many items
// the customer was able to
purchase
for (i = 0; i <
(sale_temp_Ptr->numItems); i += 2)
{
// condition to
check whether the items purchased in the
// sales list is
not zero
if
(sale_temp_Ptr->itemsPurchased[i] != 0)
{
// if so, maintain the count of the items
purchased
cust_items_count +=
sale_temp_Ptr->itemsPurchased[i + 1];
}
}
// Display the customer purchase
information
fprintf(fileOut, "\tSale #%d, %s %s
purchased %d item(s):\n",
salesCounter,
sale_temp_Ptr->firstName, sale_temp_Ptr->lastName,
cust_items_count);
// display the information of
the each item in the sales list
for (i = 0; i <
(sale_temp_Ptr->numItems); i += 2)
{
// If the item
is purchased, then display the item information and
// compute the
subtotal
if
(sale_temp_Ptr->itemsPurchased[i])
{
// set the product list to product temp
pointer
prod_temp_Ptr = kmproductList;
// traverse through each product of the product list
while (prod_temp_Ptr != NULL)
{
// condition to check if the
product list's item number matches
// with the item number in
the sales list. If matches
// display the sales and
product information and
// compute the subtotal
if (prod_temp_Ptr->itemNum
== sale_temp_Ptr->itemsPurchased[i])
{
fprintf(fileOut, "\t\t| Item %6d | %-20s | $%7.2lf (x%4d)
|\n",
sale_temp_Ptr->itemsPurchased[i],
prod_temp_Ptr->itemName,
prod_temp_Ptr->unitPrice,
sale_temp_Ptr->itemsPurchased[i + 1]);
// compute
the sub_total
sub_total
+= prod_temp_Ptr->unitPrice * sale_temp_Ptr->itemsPurchased[i
+ 1];
break;
}
// if the condition fails,
move the pointer to next node
prod_temp_Ptr =
prod_temp_Ptr->next;
}
}
}
// display the subtotal of the
items saled
fprintf(fileOut, "\t\tTotal:
$%3.2lf\n", sub_total);
// compute the totalCost
totalCost += sub_total;
// increment the sales
counter
salesCounter++;
// set the sales list to temp
pointer of sales
temp_KMS = sale_temp_Ptr;
// update the sales list
sale_temp_Ptr =
sale_temp_Ptr->next;
// free the memory set for the
itemsPurchased in the temp_KMS
free(temp_KMS->itemsPurchased);
// free the KMSales temp
node
free(temp_KMS);
}
// Display the grand total to the output file
fprintf(fileOut, "\tGrand total: $%3.2lf\n",
totalCost);
return NULL;
}
// function clear the pointer of KMProduct
KMProduct *clearKMProduct(KMProduct *kmproductList)
{
// define a KMProduct pointer to traverse through
the
// KMProduct list
KMProduct *current_ptr = kmproductList;
// declare the KMProduct pointer to hold the
current node value
// and release the memory allocated
KMProduct *temp_ptr;
// traverse through each node of the KMProduct
list
while (current_ptr != NULL)
{
// set the current node value to
temp_ptr
temp_ptr = current_ptr;
// move the current list pointer
to the next
current_ptr =
current_ptr->next;
// free the temp_ptr's
memory
free(temp_ptr);
}
// return null, inorder to reset the KMProduct
list
// to empty
return NULL;
}
// function clear the pointer of KMRestockProduct
KMRestockProduct *clearKMRestockProduct(KMRestockProduct
*kmrestockList)
{
// define a KMRestockProduct pointer to traverse
through the
// KMRestockProduct list
KMRestockProduct *current_ptr = kmrestockList;
// declare the KMRestockProduct pointer to hold the
current node value
// and release the memory allocated
KMRestockProduct *temp_ptr;
// traverse through each node of the
KMRestockProduct list
while (current_ptr != NULL)
{
// set the current node value to
temp_ptr
temp_ptr = current_ptr;
// move the current list pointer
to the next
current_ptr =
current_ptr->next;
// free the temp_ptr's
memory
free(temp_ptr);
}
// return null, inorder to reset the
KMRestockProduct list
// to empty
return NULL;
}
// function clear the pointer of KMSale
KMSale *clearKMSale(KMSale *kmsaleList)
{
// define a KMSale pointer to traverse through
the
// KMSale list
KMSale *current_ptr = kmsaleList;
// declare the KMSale pointer to hold the current
node value
// and release the memory allocated
KMSale *temp_ptr;
// traverse through each node of the KMSale
list
while (current_ptr != NULL)
{
// set the current node value to
temp_ptr
temp_ptr = current_ptr;
// move the current list pointer
to the next
current_ptr =
current_ptr->next;
// free the temp_ptr's items
purchased memory
// first
free(temp_ptr->itemsPurchased);
// then free the temp_ptr's
memory
free(temp_ptr);
}
// return null, inorder to reset the KMSale
list
// to empty
return NULL;
}
Note: Both sample input and output files are opened in note pad to show the results.
Sample Output: KnightsMart.out
Sample Input file: KnightsMart.in