Question

In: Computer Science

(Linked Lists) The Problem UCF is growing so large that they’re actually starting a mini-supermarket, KnightsMart,...

(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:

  • manages all products in the store, along with the stock (quantity) for that product
  • manages the reordering of depleted products (once the stock for that item reaches zero)
  • manages the total sales to all customers in a given day

Throughout any given day, the following things can occur (just as in a normal store):

  • New products can be added to the list of products. For example, perhaps the store doesn’t initially carry Cheerios. So this new product, Cheerios, can be added to the product line for KnightsMart. Note: when new products are added for the first time, they are initialized with a specific stock amount associated with that product. It is guaranteed that newly added items will always have a quantity of at least one unit.
  • Customers can come throughout the day to purchase items from the store. If the items are available, they are purchased, and the stock of those specific products are all reduced by the quantity purchased. If a product is not available (stock is zero), the customer simply does not purchase that product.
  • A purchase occurs when a customer finds at least one of the items they are looking for. All such purchases will need to be saved as described later in this write up. However, if a customer enters the store and all of the desired items have a stock of zero, this customer did not make a purchase, and therefore, does not need to be saved.
  • As customers purchase products, the quantity for that product is clearly reduced. Once the inventory level for a product reaches zero, that product is immediately added to a restock list.
  • Reorders can be made, and they will be based on the restock list. Products that are reordered will have their stock increased based on a fixed restock quantity associated with that particular product. For the sake of ease, whenever a REORDER command is given, we assume the restocking happens immediately (meaning, an order is not placed to some central warehouse, and then we wait for a delivery truck three days later, etc, etc.). So just assume that the items in the restock list are immediately (magically) restocked.

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:

  • KMProducts: this is an ordered linked list of products, where each node is a KMProduct (defined above). The products (nodes) of this list are in ascending order based on item number. So the first product in the list is the one whose item number is “smallest”, and the last product in the linked list is the one whose item number is largest. As such, insertion into this list must happen at the correct location, thereby maintaining the integrity of the order.
  • KMRestockList: this is a linked list of the products that need to be restocked. This list is initially NULL. Once the quantity of a product reaches zero, a new

KMRestockProduct node is made, and it is immediately added to the end of this list.

  • KMSales: this is a linked list of all the sales that occur during a given day, where each node is of type KMSale. At the beginning of each day, this list is initially NULL. Once a customer finds and therefore purchases at least one item, that sale is immediately added to the end of this list. If a customer enters the store and does not find any of the items they are looking for (all items had a current stock of zero), no sale occurred, and that customer is therefore not added to 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:

  • ADDITEM – Makes a new product which is added to the store. The command will be followed by the following information all on the same line: itemNum, an integer representing the item number for this product; itemName, the name of the item, no longer than 20 characters; unitPrice, the price of a single item; stockQty, the initial amount of stock for this product (guaranteed to be at least 1); restockQty, the quantity by which the product should be restocked whenever a reorder is placed. Each item will be unique. Meaning, the input file is guaranteed to not have duplicate items added to the store inventory via the ADDITEM command.
  • RESTOCK – This command will have no other information on the line. When this command is read, all items found in the KMRestockList are to be restocked immediately. This proceeds 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).

  • CUSTOMER – This command is for customers attempting to make purchases. It is followed by the following on the same line: a first name, then a last name, each no longer than 20 characters; an integer, n, representing two times (2x) the number of different products the customer wants to purchase, followed by n integers, which will be pairs of item numbers and the respective quantity purchased of that item number. For example, if n were six, this means the customer wants three items. Pretend those following six integers were as follows: 5437 2 8126 1 9828 4. This means the customer wants 2 units of product 5437, 1 unit of 8126, and 4 units of product number 9828.

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.

  • INVENTORY – This command will have no other information on the line. When this command is read, the current KnightsMart inventory (each item with its respective stock) is printed to the file in ascending order (the order that the product list is already in). See sample output file for specific formatting of this command. If there store does not have any inventory, an appropriate error message is printed (see sample output).
  • PRINTDAYSUMMARY – This command will have no other information on the line. When this command is read, a eport of all sales, for that given day, will be printed to the output file. Please refer to sample output for exact specifications. Once the header is printed (see sample output), all sales (nodes) found in the KMSales list will need to be printed, and then those nodes must be deleted. This will proceed as follows:

◦ 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"

Solutions

Expert Solution

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


Related Solutions

Java Problem: Array lists and linked lists are both implementations of lists. Give an example of...
Java Problem: Array lists and linked lists are both implementations of lists. Give an example of a situation where an array list would be the better choice and one where a linked list would. Explain the reasons in each case. Provide example.
1 Problem Description This lab will cover a new topic: linked lists. The basic idea of...
1 Problem Description This lab will cover a new topic: linked lists. The basic idea of a linked list is that an address or a pointer value to one object is stored within another object. By following the address or pointer value (also called a link), we may go from one object to another object. Understanding the pointer concept (which has be emphasized in previous labs and assignments) is crucial in understanding how a linked list operates. Your task will...
The marketing manager of a large supermarket chain faced the business problem of determining the effect...
The marketing manager of a large supermarket chain faced the business problem of determining the effect on the sales of pet food of shelf space and whether the product was placed at the front ​(equals​1) or back ​(equals ​0) of the aisle. Data are collected from a random sample of 12​ equal-sized stores and are given below. Complete parts​ (a) through​ (g). For parts​ (a) through​ (d), do not include an interaction term. Store Shelf_Space_(Feet) Location Weekly_Sales_($) 1 5 Back...
Linked Lists Problem 1 Implement a program that reads the following ages (type int) from text...
Linked Lists Problem 1 Implement a program that reads the following ages (type int) from text file ages.txt and stores them in a linked list: 16 18 22 24 15 31 27 19 13 Implement the class LinkedList along with any applicable member functions (e.g. void insert(int num)). Perform the following actions on the list (if applicable, use recursion): 1. Display the data in the list 2. Insert 18 at the front of the list 3. Insert 23 at the...
Python Programming Problem: If I have to separate lists, one contains a large string of paragraphs...
Python Programming Problem: If I have to separate lists, one contains a large string of paragraphs of words, and one contains just words, how can i iterate the words in my second list and compare it to my paragraph list to see how many times that word has occurred? List1 = ['paragraph.......'] List2 = ['words', 'words', 'words'......] these are just minimal examples how do i approach this problem? apprently numpy helps with processing time for something like this? cuz the...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT