0

So far I have tried to make a do...while loop where it asks two questions. One which is how many miles and the second which is how much does the package weigh. If the number of miles is equal to 0 or less it should output an error and then re-ask the question. Once validated it should move onto the weight question with the same requirements, and if the weight is invalid it should only repeat the weight question since the miles question is already valid.

This is the code that I have so far:

int miles = 0;
int choice = 0;
double weight = 0.0;


do
{
    cout << "Enter the number of miles as a whole number: ";
    cin >> miles;
    if (miles > 0)
    {
        cout << "Enter the weight of the package in pounds: ";
        cin >> weight;

        if (weight > 0 && weight < 10)
        {
            cout << "etc etc etc";
        }
        else
        {
            cout << "\n\tError: Weight must be greater than zero and less than 10 pounds!\n" << endl;
        }

    }
    else
    {
        cout << "\n\tError: Miles must be greater than zero!\n" << endl;
    }

    cout << "Enter 1 to continue or 0 to quit: ";
    cin >> choice;
    cout << endl;

}
while (choice != 0); 
cout << "\nGood-bye!\n";

return 0;  
jacko1
  • 11
  • I would suggest having separate loops for each variable you're inputting. Have a single loop where you re-prompt for number of miles until you get a positive number, then have a second loop where you re-prompt for weight until you get a valid amount. It should make it a lot easier to tell what action to take on a branch and whether you're exiting the loop correctly. – Nathan Pierson Oct 19 '20 at 22:15
  • 'continue' after the error messgae – pm100 Oct 19 '20 at 22:15
  • Here's a simple way to figure out how to do this, and it never fails to work. Just take out a blank sheet of paper. Write down using short, simple sentences in plain English, a step-by-step process of doing this. When done, [call your rubber duck for an appointment](https://en.wikipedia.org/wiki/Rubber_duck_debugging). We always refer such questions to your rubber duck. After your rubber duck approves your proposed plan of action, simply take what you've written down and translate it directly into C++. Mission accomplished! – Sam Varshavchik Oct 19 '20 at 22:18

2 Answers2

0

You can use multiple while loops, one for each input.

int miles = 0;
double weight = 0.0;
bool correct = false;

while (!correct)
{
    cout << "Enter the number of miles as a whole number: " << std::endl;
    bool success = cin >> miles;
    if (!success || miles < 0) {
        cout << "Invalid miles value -- must be nonnegative." << std::endl;
    }
    else {
        correct = true;
    }
}

correct = false;

while (!correct)
{
    cout << "Enter the weight in pounds: " << std::endl;
    bool success = cin >> weight;
    if (!success || weight < 0 || weight > 10) {
        cout << "Invalid weight value -- must be between 0 and 10." << std::endl;
    }
    else {
        correct = true;
    }
}

// do calculation

cout << "\nGood-bye!\n";

return 0;
Anonymous1847
  • 2,568
  • 10
  • 16
  • You are not validating that `cin >> ...` is successful – Remy Lebeau Oct 19 '20 at 22:33
  • If `cin >> ...` fails, `cin` enters an error state that you are not clearing (ie, if the user types in non-numeric input), which will lead to an infinite loop. – Remy Lebeau Oct 19 '20 at 22:37
  • And, even better, put those multiple loops into multiple functions, one for each loop. Then look for similarities and maybe consolidate the functions. – Pete Becker Oct 20 '20 at 02:23
0

You need additional loops to read from cin until the input is valid. And you need to ensure that cin is even successful in reading a value before you perform range checking on that value.

I would suggest doing the read+validation in a separate function, eg:

#include <iostream>
#include <limits>

template<typename T>
T prompt(const char *msg, T maxValue = std::numeric_limits<T>::max())
{
    T value;

    do
    {
        cout << msg << ": ";

        if (!(cin >> value))
        {
            cout << "\n\tError: Invalid input!\n" << endl;
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        else if (value < 0)
        {
            cout << "\n\tError: Value must be greater than 0!\n" << endl;
        }
        else if (value >= maxValue)
        {
            cout << "\n\tError: Value must be less than " << maxValue << "!\n" << endl;
        }
        else
            break;
    }
    while (true);

    return value;
}

...

int miles;
double weight;
int choice;

do
{
    miles = prompt<int>("Enter the number of miles as a whole number");
    weight = prompt<double>("Enter the weight of the package in pounds", 10.0);
    choice = prompt<int>("Enter 1 to continue or 0 to quit", 2);
    cout << endl;
}
while (choice != 0); 

cout << "\nGood-bye!\n";
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770