vendor-info/vendorInfo.c

284 lines
5.4 KiB
C

/*
* vendorInfo.c
*
* Program that
*
*
* Created by Win (Thanawin Pattanaphol), 28th August 2024
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_VENDORS 20
#define MAX_FILENAME_LENGTH 4096
/* STRUCTURES */
struct vendor
{
char vendor_name[20];
char merchandise[15];
int inventory_count;
int item_price_baht;
} vendors[MAX_VENDORS];
struct search_r
{
int status;
int item_id;
};
struct purchase_r
{
int status;
char vendor_name[20];
int price_owe_baht;
};
/* FUNCTION DECLARATION */
int read_input(char str[], size_t n);
char *strnlower(char *s, size_t n);
int validate_data(struct vendor vendors[MAX_VENDORS]);
struct search_r search
(
char query[],
struct vendor vendors[MAX_VENDORS],
int total_vendors
);
struct purchase_r purchase
(
int item_id,
int amount,
struct vendor vendors[MAX_VENDORS]
);
int main()
{
char file_name[MAX_FILENAME_LENGTH];
printf("Enter name of input file: ");
read_input(file_name, MAX_FILENAME_LENGTH);
FILE *fp;
if ((fp = fopen(file_name, "r")) == NULL)
{
printf("%s cannot be opened.\n", file_name);
exit(EXIT_FAILURE);
}
// calculate file size
fseek(fp, 0, SEEK_END);
unsigned long file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
// read file to buffer
char *file_buffer = (char *) malloc(file_size);
int index = 0;
while ((fgets(file_buffer, 50, fp) != NULL) && (index <= MAX_VENDORS))
{
/* TO-DO: VALIDATE FILE DATA */
char *token = strtok(file_buffer, " ");
strncpy(vendors[index].vendor_name, token, strlen(token) + 1);
token = strtok(NULL, " ");
/* TO-DO: VALIDATE MERCHANDISE BY PUTTING EVERYTHING AS LOWERCASE */
strncpy(vendors[index].merchandise, token, strlen(token) + 1);
token = strtok(NULL, " ");
vendors[index].inventory_count = atoi(token);
token = strtok(NULL, " ");
vendors[index].item_price_baht = atoi(token);
index++;
}
int total_vendors = index - 1;
printf("\n>>> Read %d vendors from file %s\n", total_vendors, file_name);
// print out each vendor's info
for (int i = 0; i <= total_vendors; i++)
{
char vendor_info[200];
sprintf(vendor_info, "%s sells %s for %d each",
vendors[i].vendor_name,
vendors[i].merchandise,
vendors[i].item_price_baht
);
char vendor_stock[50];
sprintf(vendor_stock, "Inventory %d items",
vendors[i].inventory_count
);
printf("%-50s %s\n", vendor_info, vendor_stock);
}
while (1)
{
char user_query[100];
printf("What do you want to buy? (DONE to end) ");
read_input(user_query, 100);
if ((strcmp(user_query, "DONE") == 0))
{
break;
}
// convert string to lowercase - each character one by one
int user_query_length = strlen(user_query);
strnlower(user_query, user_query_length);
struct search_r item = search(user_query, vendors, total_vendors);
if(item.status == 0)
{
char input[10];
read_input(input, 10);
if(atoi(input) < 0)
{
int item_amount = atoi(input);
struct purchase_r response = purchase(item.item_id, item_amount, vendors);
if (response.status == 0)
{
printf("You owe %s a total of %d baht.\n",
response.vendor_name,
response.price_owe_baht
);
}
}
else
{
printf("You must enter a positive whole number for the number of items");
}
}
else
{
printf("No vendor in this market sells %s\n", user_query);
}
}
fclose(fp);
free(file_buffer);
return 0;
};
/*
read_input: Custom read input function
str = string itself
n = max amount of characters that the function is able to read into buffer
reads one character at a time into buffer and adds a null terminator when finish reading
*/
int read_input(char str[], size_t n)
{
int ch, i = 0;
while ((ch = getchar()) != '\n')
{
if (i < (int)n)
{
str[i++] = ch;
}
}
str[i] = '\0';
return i;
};
/*
strnlower: Convert string to lowercase
Parameters:
- s: String
- n: Length of string
*/
char *strnlower(char *s, size_t n)
{
for (int i = 0; i < (int) n; i++)
{
s[i] = tolower(s[i]);
};
}
/*
Search function
Parameters:
- query: search query
- vendors: the vendor table
- total_vendors: the amount of vendors
Return values:
- i: Item Number
- 0: No results found
*/
/* TO-DO IMPLEMENT RESPONSE STRUCT */
struct search_r search(char query[], struct vendor vendors[MAX_VENDORS], int total_vendors)
{
int i;
for (i = 0; i < total_vendors; i++)
{
if (strcmp(query, vendors[i].merchandise) == 0)
{
struct search_r response;
response.status = 0;
response.item_id = i;
return (response);
break;
};
};
if (i == total_vendors)
{
struct search_r response;
response.status = 1;
response.item_id = 0;
return (response);
}
};
/*
Purchase function
Parameters:
- item_id: The item id that the user is purchasing
- amount: How many items that the user is purchasing
- vendors: vendor table
Return values:
-
*/
struct purchase_r purchase(int item_id, int amount, struct vendor vendors[MAX_VENDORS])
{
if(amount <= vendors[item_id].inventory_count)
{
// Decrease vendor inventory
vendors[item_id].inventory_count = vendors[item_id].inventory_count - amount;
struct purchase_r response;
response.status = 0;
strcpy(response.vendor_name, vendors[item_id].vendor_name);
response.price_owe_baht = vendors[item_id].item_price_baht * amount;
return (response);
}
else
{
struct purchase_r response;
response.status = 1;
return response;
}
};