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
