Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Milestone 2 Definitions
#define LINEAR 1
#define FORM 0
//Milestone 3 Definitions
#define STOCK 1
#define CHECKOUT 0
#define MAX_QTY 999
#define SKU_MAX 999
#define SKU_MIN 100
//Milestone 4 Definitions
#define MAX_ITEM_NO 500 //redefined from 21 in ms3
#define DATAFILE "items.txt"
//Milestone 1 Prototypes
void welcome(void);
void flushKeyboard(void);
void pause(void);
int yes(void);
int getInt(void);
int getIntLimited(int lowerLimit, int upperLimit);
double getDouble(void);
double getDoubleLimited(double lowerLimit, double upperLimit);
void GrocInvSys(void);
int menu(void);
void printTitle(void);
void printFooter(double grandtotal);
//app interface
void GroceryInventorySystem(void)
{
int menuSelection;
int exitSelection = 0;
welcome();
printf("\n");
while (exitSelection == 0) {
menuSelection = menu();
switch(menuSelection)
{
case 1:
printf("List items under construction!\n");
pause();
break;
case 2:
printf("Search Items under construction!\n");
pause();
break;
case 3:
printf("Checkout Item under construction!\n");
pause();
break;
case 4:
printf("Stock Item under construction!\n");
pause();
break;
case 5:
printf("Add/Update Item under construction!\n");
pause();
break;
case 6:
printf("Delete Item under construction!\n");
pause();
break;
case 7:
printf("Search by name under construction!\n");
pause();
break;
default:
printf("Exit the program? (Y)es/(N)o: ");
exitSelection = yes();
break;
}
}
}
int yes(void)
{
char YN;
begin:;
scanf("%c", &YN);
flushKeyboard();
if (YN == 'N' || YN == 'n') {
return 0;
}
else if (YN == 'Y' || YN == 'y') {
return 1;
}
else {
printf("Only (Y)es or (N)o are acceptable: ");
goto begin;
}
}
int menu(void) {
int option;
int firstSelection = 0;
int lastSelection = 7;
printf("1- List all items\n");
printf("2- Search by SKU\n");
printf("3- Checkout an item\n");
printf("4- Stock an item\n");
printf("5- Add new item or update item\n");
printf("6- Delete item\n");
printf("7- Search by name\n");
printf("0- Exit program\n");
printf("> ");
option = getIntLimited(firstSelection, lastSelection);
return option;
}
const double TAX = 0.13;
//Milestone 2 Structure/Prototypes
struct Item { //keeps item related information
double price; //price of a unit of the item
int sku; //stock keeping unit, a 3 digit integer
int isTaxed; //an integer flag, if true (non-zero), the tax is applied in price calculation. The value of tax is kept in the global constant TAX variable.
int quantity; //the quantity of the time in the inventory.
int minQuantity;//the mininum quantity number in inventory; any inventory quantity value less than this will cause a warning to order more of this item later in development
char name[21]; //a 20 character, C string (i.e a 21 character NULL terminated array of characters) to keep the name of the item.
};
double totalAfterTax(struct Item item);
int isLowQuantity(struct Item item);
struct Item itemEntry(int sku);
void displayItem(struct Item item, int linear);
void listItems(const struct Item item[], int noOfItems);
int locateItem(const struct Item item[], int NoOfRecs, int sku, int* index);
//Milestone 3 Prototypes
void search(const struct Item item[], int NoOfRecs);
void updateItem(struct Item* itemptr);
void addItem(struct Item item[], int *NoOfRecs, int sku);
void addOrUpdateItem(struct Item item[], int* NoOfRecs);
void adjustQuantity(struct Item item[], int NoOfRecs, int stock);
//Milestone 4 Prototypes
void saveItem(struct Item item, FILE* dataFile);
int loadItem(struct Item* item, FILE* datafile);
int saveItems(const struct Item item[], char fileName[], int NoOfRecs);
int loadItems(struct Item item[], char fileName[], int* NoOfRecsPtr);
void prnFile() {
FILE* tp = fopen("test.txt", "r");
char ch;
if (tp) {
for (; fscanf(tp,"%c", &ch) == 1; putchar(ch));
fclose(tp);
}
else {
printf("text.txt not found\n");
}
}
int main(void) {
int i, n;
struct Item GI[3] = {
{ 4.4,275,0,10,2,"Royal Gala Apples" },
{ 5.99,386,0,20,4,"Honeydew Melon" },
{ 3.99,240,0,30,5,"Blueberries" },
};
struct Item I;
struct Item IN[3];
printf("Testing saveItem:\n");
printf("Your saveItem saved the following in test.txt: \n");
FILE *tp = fopen("test.txt", "w");
if (tp) {
for (i = 0; i < 3; i++) saveItem(GI[i], tp);
fclose(tp);
prnFile();
}
printf("*******************************\nThey have the match the following:\n");
printf("275,10,2,4.40,0,Royal Gala Apples\n");
printf("386,20,4,5.99,0,Honeydew Melon\n");
printf("240,30,5,3.99,0,Blueberries\n");
printf("END Testing saveItem!\n\n\n");
pause();
printf("Testing loadItem:\n");
printf("Your loadItem loaded the following from test.txt: \n");
tp = fopen("test.txt", "r");
if (tp) {
for (i = 0; i < 3; i++) {
loadItem(&I, tp);
displayItem(I, LINEAR);
}
fclose(tp);
tp = fopen("test.txt", "w");
fclose(tp);
}
printf("*******************************\nThey have to match the following:\n");
printf("|275|Royal Gala Apples | 4.40| No| 10 | 2 | 44.00|\n");
printf("|386|Honeydew Melon | 5.99| No| 20 | 4 | 119.80|\n");
printf("|240|Blueberries | 3.99| No| 30 | 5 | 119.70|\n");
printf("END Testing loadItem!\n\n\n");
pause();
printf("Testing saveItems:\n");
printf("Your saveItems saved the following in test.txt: \n");
saveItems(GI, "test.txt", 3);
prnFile();
printf("*******************************\nThey have to match the following:\n");
printf("275,10,2,4.40,0,Royal Gala Apples\n");
printf("386,20,4,5.99,0,Honeydew Melon\n");
printf("240,30,5,3.99,0,Blueberries\n");
printf("END Testing saveItems!\n\n\n");
pause();
printf("Testing loadItems:\n");
printf("Your loadItems loaded the following from test.txt: \n");
loadItems(IN, "test.txt", &n);
for (i = 0; i < n; i++) {
displayItem(IN[i], LINEAR);
}
printf("*******************************\nThey have to match the following:\n");
printf("|275|Royal Gala Apples | 4.40| No| 10 | 2 | 44.00|\n");
printf("|386|Honeydew Melon | 5.99| No| 20 | 4 | 119.80|\n");
printf("|240|Blueberries | 3.99| No| 30 | 5 | 119.70|\n");
printf("**********END Testing loadItems!\n\n\n");
pause();
printf("Done!\n");
return 0;
}
//code your functions here:
//Milestone 1 Functions
void welcome(void)
{
printf("---=== Grocery Inventory System ===---");
printf("\n");
return;
}
void printTitle(void)
{
printf("Row |SKU| Name | Price |Taxed| Qty | Min | Total |Atn\n");
printf("----+---+---------------+-------+-----+-----+-----+-------------|---");
printf("\n");
return;
}
void printFooter(double grandTotal)
{
printf("--------------------------------------------------+-----------------");
printf("\n");
if (grandTotal > 0) {
printf(" Grand Total: | %12.2lf", grandTotal);
}
return;
}
void flushKeyboard(void)
{
int read;
while (( read = getchar()) != '\n' && read != EOF) {
continue;
}
return;
}
void pause(void)
{
printf("Press <ENTER> to continue...");
flushKeyboard();
return;
}
int getInt(void)
{
int Value;
char NL = 'x';
while (scanf("%d%c", &Value, &NL) != 2 || NL != '\n') {
flushKeyboard();
printf("Invalid integer, please try again: ");
}
return Value;
}
int getIntLimited(int lowerLimit, int upperLimit)
{
int result;
do {
result = getInt();
if(lowerLimit > result || upperLimit < result) {
printf("Invalid value, %d < value < %d: ", lowerLimit, upperLimit);
}
} while(result < lowerLimit || result > upperLimit);
return result;
}
double getDouble(void)
{
double value = 0;
char NL = 'x';
while (scanf("%lf%c", &value, &NL) !=2 || NL !='\n') {
flushKeyboard();
printf("Invalid double, please try again");
}
return value;
}
double getDoubleLimited(double lowerLimit, double upperLimit)
{
double result2;
do {
result2 = getDouble();
if(lowerLimit > result2 || upperLimit < result2) {
printf("Invalid value, %lf < value %lf: ", lowerLimit, upperLimit);
}
} while(result2 < lowerLimit || result2 > upperLimit);
return result2;
}
//Milestone 2 Functions
double totalAfterTax(struct Item item)
{
double cost;
if (item.isTaxed == 1) {
cost = item.price * item.quantity * 1 + TAX;
}
else {
cost = item.price * item.quantity;
}
return cost;
}
int isLowQuantity(struct Item item)
{
if(item.quantity < item.minQuantity) {
return 1;
}
return 0;
}
struct Item itemEntry(int sku) {
struct Item itemEntry;
itemEntry.sku = sku;
printf(" SKU: %d\n", sku);
printf(" Name: ");
scanf("%20[^\n]", itemEntry.name);
flushKeyboard();
printf(" Price: ");
itemEntry.price = getDoubleLimited(0.01, 1000.00);
printf(" Quantity: ");
itemEntry.quantity = getIntLimited(1, MAX_QTY);
printf("Minimum Quantity: ");
itemEntry.minQuantity = getIntLimited(0, 100);
printf(" Is Taxed: ");
itemEntry.isTaxed = yes();
return itemEntry;
}
void displayItem(struct Item item, int linear)
{
char *taxCheck[4];
double total;
if(item.isTaxed == 1) {
*taxCheck = "Yes";
total = item.price*item.quantity*(1+TAX);
}
else {
*taxCheck = "No";
total = item.price*item.quantity;
}
if(linear == LINEAR) {
printf("|%3d|%-20s|%8.2lf| %3s| %3d | %3d |%12.2lf|", item.sku, item.name, item.price, *taxCheck, item.quantity, item.minQuantity, total);
if (item.quantity < item.minQuantity) {
printf("***\n");
}
else {
printf("\n");
}
}
else {
printf("SKU: %d\n"
"Name: %s\n"
"Price: %.2lf\n"
"Quantity: %d\n"
"Minimum Qty: %d\n"
"Is Taxed: %s\n", item.sku, item.name, item.price, item.quantity, item.minQuantity, *taxCheck);
if(item.quantity < item.minQuantity) {
printf("WARNING: Quantity low, please order ASAP!!!\n");
}
}
}
void listItems(const struct Item item[], int noOfItems)
{
int i;
double grandtotal =0;
for (i = 0; i < noOfItems; i++) {
printf("%-4d", (i + 1));
displayItem(item[i], LINEAR);
grandtotal += totalAfterTax(item[i]);
}
printFooter(grandtotal);
printf("\n");
}
int locateItem(const struct Item item[], int NoOfRecs, int sku, int* index)
{
int i;
int flag = 0;
for(i = 0; i < NoOfRecs; i++) {
if(sku == item[i].sku) {
*index = i;
flag = 1;
}
}
return flag;
}
//Milestone 3 functions
void search(const struct Item item[], int NoOfRecs)
{
int enterSKU;
int locate;
int index;
printf("Please enter the SKU: ");
enterSKU = getIntLimited(SKU_MIN, SKU_MAX);
locate = locateItem(item, NoOfRecs, enterSKU, &index);
if(locate == 1) {
displayItem(item[index], FORM);
}
else {
printf("Item not found!\n");
}
}
void updateItem(struct Item* itemptr)
{
struct Item item;
int confirm;
printf("Enter new data:\n");
item = itemEntry(itemptr->sku);
printf("Overwrite old data? (Y)es/(N)o: ");
confirm = yes();
if (confirm == 1) {
printf("--== Updated! ==--\n");
*itemptr = item;
}
else {
printf("--== Aborted! ==--\n");
}
}
void addItem (struct Item item[], int *NoOfRecs, int sku)
{
struct Item add;
int update;
if(*NoOfRecs == MAX_ITEM_NO) {
printf("Can not add new item; Storage Full!\n");
}
else {
add = itemEntry(sku);
printf("Add Item? (Y)es/(N)o: ");
update = yes();
if(update == 1) {
item[*NoOfRecs] = add;
(*NoOfRecs)++;
printf("--== Added! ==--\n");
}
else {
printf("--== Aborted! ==--\n");
}
}
}
void addOrUpdateItem(struct Item item[], int* NoOfRecs)
{
int inputSKU;
int findItem;
int index;
int verify = 0;
printf("Please enter the SKU: ");
inputSKU = getIntLimited(SKU_MIN, SKU_MAX);
findItem = locateItem(item, *NoOfRecs, inputSKU, &index);
if(findItem == 1) {
displayItem(item[index], FORM);
printf("Item already exists, Update? (Y)es/(N)o: ");
verify = yes();
if(verify == 1){
updateItem(&item[index]);
}
}
else if(verify != 1) {
printf("--== Aborted! ==--\n");
}
else {
addItem(item, NoOfRecs, inputSKU);
}
}
void adjustQuantity(struct Item item[], int NoOfRecs, int stock)
{
int validSKU;
int quantity;
int index;
int search;
int i = 0;
printf("Please enter the SKU: ");
validSKU = getIntLimited(SKU_MIN, SKU_MAX);
search = locateItem(item, NoOfRecs, validSKU, &index);
if(search != 1) {
printf("SKU not found in storage!\n");
}
else {
displayItem(item[index], FORM);
if (stock == STOCK) {
printf("Please enter the quantity to stock; Maximum of %d or 0 to abort: ", MAX_QTY - item[index].quantity);
quantity = getIntLimited(0, (MAX_QTY - item[index].quantity));
if (quantity == 0) {
printf("--== Aborted! ==--\n");
}
else {
item[index].quantity += quantity;
printf("--== Stocked! ==--\n");
}
}
else if(stock == CHECKOUT) {
printf("Please enter the quantity to checkout; Maximum of %d or 0 to abort: ", item[index].quantity);
quantity = getIntLimited(0, item[index].quantity);
if(quantity == 0) {
printf("--== Aborted! ==--\n");
}
else {
item[index].quantity -= quantity;
printf("--== Checked out! ==--\n");
}
}
if (item[i].quantity < item[i].minQuantity) {
printf("Quantity is low, please reorder ASAP!!!\n");
}
}
}
void saveItem(struct Item item, FILE* datafile)
{
fprintf(datafile, "%d,%d,%d,%.2lf,%d,%s\n", item.sku, item.quantity, item.minQuantity, item.price, item.isTaxed, item.name);
}
int loadItem(struct Item* item, FILE* datafile)
{
int load;
fscanf(datafile, "%d,%d,%d,%f,%d,%[^\n]", &item->sku, &item->quantity, &item->minQuantity, &item->price, &item->isTaxed, item->name);
load = fscanf(datafile, "%d,%d,%d,%lf,%d,%[^\n]", &item->sku, &item->quantity, &item->minQuantity, &item->price, &item->isTaxed, item->name);
if (load == 1) {
return 1;
}
else {
return 0;
}
}
int saveItems(const struct Item item[], char filename[], int NoOfRecs)
{
int i;
FILE *fp = fopen("test.txt", "w");
if (fp != NULL) {
return 0;
}
else {
for (i = 0; i < NoOfRecs; i++);
saveItem(item[i], fp);
}
fclose(fp);
return 1;
}
int loadItems(struct Item item[], char fileName[], int* NoOfRecsPtr)
{
int i;
FILE *fp = fopen("test.txt", "r");
if (fp != NULL) {
return 0;
}
else {
for(i = 0; i < 4; i++);
loadItem(&item[i], fp);
*NoOfRecsPtr = i;
}
fclose(fp);
return 1;
}