/* * vendorInfo.c * * Program that * * * Created by Win (Thanawin Pattanaphol), 28th August 2024 */ #include #include #include #include #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; } };