my code has logical error i think, if I enter a number greater than max, the error void will show up, but the it still proceed on addOrder. I want to loop it if the user input is invalid it will clear the buffer and the user will input again. Can you please help me?
my code has logical error i think, if I enter a number greater than max, the error void will show up, but the it still proceed on addOrder. I want to loop it if the user input is invalid it will clear the buffer and the user will input again. Can you please help me?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h> //for sleep function
//for color text
#define Reset_txt "\033[0m"
#define Red_txt "\033[0;31m"
#define Green_txt "\033[0;32m"
// Global variables
int userChoice;
char productNames[3][50];
double prices[3]; // this arrays used to stores the data price of different orders and prices
double payment = 0;
double userchanges[3];
double userMoney[3];
char Spag[50] = "Spaghetti";
char Pal[50] = "Palabok";
char Chic[50] = "Chicken";
int order = 0;
// Function to display an error message
void error()
{
printf(Red_txt "Invalid input!\n" Reset_txt);
return;
}
// Function to simulate ordering food
void loadingScreen()
{
int i;
printf("Loading: ");
for (i = 0; i < 20; ++i)
{
printf("*");
fflush(stdout);// Flush the standard output buffer to ensure the asterisk is visible
usleep(100000);// Introduce a delay of 100,000 microseconds (0.1 seconds)
}
// Provide a prompt for the user to order their meal
printf(Green_txt "\nOrder Successful!\n" Reset_txt);
}
// Display a loading animation
void orderFood()
{
int i;
printf("Loading: ");
for (i = 0; i < 20; ++i)
{
printf("*");
fflush(stdout);// Flush the standard output buffer to ensure the asterisk is visible
usleep(100000);// Introduce a delay of 100,000 microseconds (0.1 seconds)
}
// Provide a prompt for the user to order their meal
printf(" \nPlease order your meal.\n");
}
// Function to check if input is a valid number
int isValid(char *input)
{
// Check if the input is empty or consists of only whitespace
if (input == NULL || strspn(input, " \t\n") == strlen(input))
return 0;
char *endptr;
// Try to convert the input to a number (integer or floating-point)
strtod(input, &endptr);
// If the conversion reaches the end of the string (no error), it's a valid number
return *endptr == '\0';
}
// Function to get user input within a specified range
int getInp(char *inputType, int max) //max: The maximum allowed value for the input
{
// Declare an array to store user input and initialize a variable for valid input
char userInp[50];
int valid = 0;
while (!valid)
{
printf("%s", inputType); // Display the inputType prompt
// Read user input using fgets
if (fgets(userInp, sizeof(userInp), stdin) == NULL)
{
error();
continue;
}
// Remove newline character from user input
userInp[strcspn(userInp, "\n")] = 0;
if (isValid(userInp) == 1) // Check if the input is a valid number
{
valid = atoi(userInp); // Convert the valid input to an integer
if (valid < 0 || valid > max) // Check if the input is within the specified range
{
error(); // If not, display an error and continue the loop
continue;
}
else
{
break; // If valid input is received, break out of the loop
}
}
else
{
error(); // If the input is not a valid number, display an error and continue the loop
continue;
}
}
return valid; // Return the valid user input
}
void menu(int order)
{
orderFood();//void orderFood calling
printf("|=======================|\n");
printf("| Menu |\n");
printf("|=======================|\n");
printf("| Prices: |\n");
printf("| [1] Spaghetti: 150.00 |\n");
printf("| [2] Palabok: 120.00 |\n");
printf("| [3] Chicken: 160.00 |\n");
printf("|=======================|\n");
// Check if the userChoice is out of range
userChoice = getInp("Please select your order: ", 3); //max value 3
if (userChoice < 1 || userChoice > 3)
{
error();
}
switch (userChoice)
{
case 1:
strcpy(productNames[order], Spag); // Set the product name to Spaghetti
prices[order] = 150.00; // Set the price for Spaghetti
break; // Exit the switch statement
case 2:
strcpy(productNames[order], Pal); // Set the product name to Palabok
prices[order] = 120.00; // Set the price for Palabok
break; // Exit the switch statement
case 3:
strcpy(productNames[order], Chic); // Set the product name to Chicken
prices[order] = 160.00; // Set the price for Chicken
break; // Exit the switch statement
default:
// If the user enters an invalid choice
break; // Exit the switch statement
error();
getch();
system("cls");
menu(order);
}
AddOrder(); // Proceed to the next step, which is adding the order
}
// Function to ask if the user wants to add another order
void AddOrder()
{
int addOrder;
order++;
addOrder = getInp("Do you want to add another order? ([1] = Yes | [2] = No): ", 2); //maxvalue 2
// Check if addOrder is out of range
if (addOrder < 1 || addOrder > 2)
{
error(); // will call error if it doesn't meet the condition
getch(); // will read any char in keyboard
system("cls"); //to clear the console
menu(order); //calling the menu(order) void
}
else if (addOrder == 1) // if the user input 1 it will proceed to cls and menu(order)
{
system("cls");
menu(order);
}
else // if the user input 2 it will proceed to receipt
{
loadingScreen();
getch();
system("cls");
receipt();
}
}
// Function to display the receipt
void receipt()
{
// Initialize variables to store the total amount, user changes, and money
double TotalAmount = 0.0;
double Totaluserchanges = 0.0;
double TotalMoney = 0.0;
printf("==============================\n");
printf("Receipt: \n");
printf("==============================\n");
// Loop through each ordered item
for (int i = 0; i < order; i++)
{
printf("Food selected: %s\n", productNames[i], i + 1);//Print the selected food and its index
printf("Product price: P%.2lf\n", prices[i], i + 1); // Print the price of the selected food
TotalAmount += prices[i]; // Accumulate the total amount of the order
TotalMoney += userMoney[i]; Accumulate the total money received
Totaluserchanges += userchanges[i]; / Accumulate the total change for each order
}
printf("Total amount of product: P%.2lf\n", TotalAmount);
do
{
//the user ask to input money
printf("Enter the amount of money: ");
scanf("%lf", &TotalMoney);
if (TotalMoney < TotalAmount)
{
printf(Red_txt"Insufficient money\n"Reset_txt);//if the totalMoney is lessthan totalAmou
while(getchar() != '\n'); // Clear the buffer
}
else
{
Totaluserchanges = TotalMoney - TotalAmount; // to get the userchange
break; // get the total change of user
}
} while(1);
// Calculate the total user changes by iterating through each order
for (int i = 0; i < order; i++)
{
Totaluserchanges += userchanges[i];
}
// Display the total amounts and changes
printf("==========================\n");
printf("Total amount of product: P%.2lf\n", TotalAmount);//print the total amount of products
printf("Total amount of money: P%.2lf\n", TotalMoney); //total money of the user
printf("Total change: P%.2lf\n", Totaluserchanges); //total change of the user
}
int main()
{
menu(order);
}
First I had to fix some syntax errors (missing comments characters) and as I don't have
getch()
on my system I changed those togetchar()
which you are also using. Also,i + 1
had no associated format string inreceipt()
and missing function declarations.In
menu()
you ask the user to make a choice:but continue along both in the the normal or error case. The intention is for
getInp()
to only return with valid data so there shouldn't be a need to check it again.In
getInp()
you check for our of range with:so we call
getInp(..., 3)
and with input4
thevalid < 0 || valid > max
is true as4 > 3
yet you do not setvalid = 0
so it remains1
and the incorrect value is returned.Back in
menu()
you you evaluate the user choice in a switch but you shouldn't need thedefault
case if the previous worked as expected. Thedefault
case starts with abreak;
so the remaining code never runs so you should either remove it or move thebreak;
till after the other code.I would add a
min
argument togetInp()
and simplify it's implementation by usingsscanf()
. Also, display better errors for easier debugging:and example partial run:
There are many other issues like:
clear()
function instead ofsystem("cls")
const
when possibleconst char Spag[] = "Spaghetti";
)