While loop problem

Hello, I was given an assignment to create a program that will give summery about ones water consumption.
i-the gallons used,
ii-the amount equivalent to the gallons used based on price per gallons provided,
ii-tax that would be added
iii- the total monthly fee( tax plus equivalent gallons amount).
After taking inputs from the user the program should tell the user if they are domestic(less than or equal to 500gals), Commercial(if greater than 500 but less than 1000gals), and industrial(if more than 1000gals) used.
Then show them their amount to pay for the month.
but the customer name should be of string type and all the other variables should be float.

The question looks simple enough. and was able to do something meaningful below.

#include <iostream>

using namespace std;

int main()

{

cout <<"\t\t\t Welcome to countryxxx Water electronic statement system."<<endl;

string name;

float galons;

cout <<"Enter Customer Name: ";

getline (cin, name);

cout <<"Enter number of Galons used : ";

cin>>galons;

//tariffs

float Amt_domestic=galons*0.25; //domestic tariff

float Amt_commercial=galons*0.35; // commercial tariff

float Amt_industrial=galons*0.50; //industrial tariff

//Domestic amounts

float projects=0.02*Amt_domestic;

float Total_Payable=Amt_domestic+projects;

//commercial amounts

float projects_c=0.02*Amt_commercial;

float Total_Payable_c=Amt_commercial+projects_c;

//Industrial amounts

float projects_i= Amt_industrial*0.02;

float Total_Payable_i=Amt_industrial+projects_i;

//Halt due to characters or string entered into float

if(!cin){

cout<<"Error Try again, Enter numbers only in Gallons field"<<endl;}

//Domestic

else if(galons<=500){

cout<<endl<<"Hello "<<name<<","<<endl;

cout <<"You have used "<<galons<<" Gallons of water for the month, making you a DOMESTIC USER."<<endl;

cout <<"You have consumed $"<<Amt_domestic<<" worth of Water."<<endl;

cout <<"The 2% Taxation fee for Fire and Rural projects is $"<<projects<<endl;

cout <<endl<<"\t You will pay a total of $"<<Total_Payable<<" for the month."<<endl;}

//Commercial

else if(galons>500 && galons <=1000){

cout<<endl<<"Hello "<<name<<","<<endl;

cout <<"You have used "<<galons<<" Gallons of water for the month, making you a COMMERCIAL user."<<endl;

cout <<"You have consumed $"<<Amt_commercial<<" worth of Water."<<endl;

cout <<"The 2% Taxation fee for Fire and Rural projects is $"<<projects_c<<endl;

cout <<endl<<"\t You will pay a total of $"<<Total_Payable_c<<" for the month."<<endl;

}

//Industrial

else if(galons>1000){

cout<<endl<<"Hello "<<name<<","<<endl;

cout <<"You have used "<<galons<<" Gallons of water for the month, making you an INDUSTRIAL consumer."<<endl;

cout <<"You have consumed %"<<Amt_industrial<<" worth of Water."<<endl;

cout <<"The 2% Taxation fee for Fire and Rural projects is $"<<projects_i<<endl;

cout <<endl<<"\t You will pay a total of $"<<Total_Payable_i<<" for the month."<<endl;

}

cout<<endl<<"Thank You, have a great day."<<endl;

return 0;

}

At least it got all the requirements of the question. And has been submitted.
But i wanted it to be like if the user enters a char or string into gallons, the program should display, wrong input at gallons field enter number only, THEN ask if they would like to repeat with (y/n).
If they do the program should start from the user input again until gallons have float type. infact i was able to come up with that with my first if condition. but the program does not repeat. it shuts down.
I tried with while loop at the top and the program becomes a mess if alphabet is entered into gallons.
especially with the getline part.
Please any ideas would be much appreciated.

I would actually make a helper function that checks for valid input. Something like

// -----------------------------------------------------------------------------
/**
  @brief Get user input integer

  @param[in] userPrompt  text for user prompt
  @param[out] input      user input integer

  @return  An error code: 0 - success, otherwise - failure
**/
// -----------------------------------------------------------------------------
int getUserInt(char *userPrompt, FILE *stream, int *input) {
  char *p, s[100];
  int n = 0;

  // Get user input with given prompt
  printf("%s", userPrompt);
  while (fgets(s, sizeof(s), stream)) {
    n = strtol(s, &p, 10);
    // Check for integer
    if (p == s || *p != '\n')
      printf("%s", userPrompt);
    else
      break;
  }

  // Save user input
  *input = n;

  return 0;
};

This one is a bit come complex than what you have in your code, but the basic ideas are there. This is for C instead of C++, but let me know what parts of the code you’d like me to explain.

Here is an example of using the above function to get an integer in a range

// -----------------------------------------------------------------------------
/**
  @brief Get user input integer from a range

  @param[in] userPrompt  text for user prompt
  @param[in] lower       lower end of range, inclusive
  @param[in] upper       upper end of range, inclusive
  @param[out] input      user input integer

  @return  An error code: 0 - success, otherwise - failure
**/
// -----------------------------------------------------------------------------
int getValidUserInt(char *userPrompt, FILE *stream, int lower, int upper,
                    int *input) {
  bool valid = false;

  // Loop until valid
  while (!valid) {
    getUserInt(userPrompt, stream, input);
    if (*input < lower || *input > upper)
      printf("Invalid input! Provide a value in the range [%d - %d].\n", lower,
             upper);
    else
      valid = true;
  }

  return 0;
};

Even though it is quite complex for my standard now, i will still try to make it meaningful.
Thank you, very much. :pray:

I would be happy to explain any parts of my code. I figure that you wouldn’t use this directly but could maybe draw inspiration from the code?