Как проверить ввод в цикле do … while, а затем при необходимости повторно задать вопрос?

#c #loops #validation #input #do-while

#c #циклы #проверка #ввод #do-while

Вопрос:

До сих пор я пытался создать цикл do … while, в котором он задает два вопроса. Один — сколько миль, а второй — сколько весит пакет. Если количество миль равно 0 или меньше, оно должно выдать ошибку, а затем повторно задать вопрос. После проверки он должен перейти к вопросу о весе с теми же требованиями, и если вес недействителен, он должен только повторить вопрос о весе, поскольку вопрос о милях уже действителен.

Это код, который у меня есть до сих пор:

 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 amp;amp; weight < 10)
        {
            cout << "etc etc etc";
        }
        else
        {
            cout << "ntError: Weight must be greater than zero and less than 10 pounds!n" << endl;
        }

    }
    else
    {
        cout << "ntError: 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;  
  

Комментарии:

1. Я бы предложил иметь отдельные циклы для каждой вводимой переменной. Есть один цикл, в котором вы повторно запрашиваете количество миль, пока не получите положительное число, затем есть второй цикл, в котором вы повторно запрашиваете вес, пока не получите действительное количество. Должно быть намного проще определить, какое действие предпринять в ветке и правильно ли вы выходите из цикла.

2. «продолжить» после сообщения об ошибке

3. Вот простой способ выяснить, как это сделать, и он никогда не перестает работать. Просто достаньте чистый лист бумаги. Запишите, используя короткие простые предложения на простом английском языке, пошаговый процесс выполнения этого. Когда закончите, позвоните своей резиновой утке для назначения . Мы всегда отсылаем такие вопросы к вашей резиновой утке. После того, как ваша резиновая утка одобрит предложенный вами план действий, просто возьмите то, что вы записали, и переведите это непосредственно на C . Миссия выполнена!

Ответ №1:

Вам нужны дополнительные циклы для чтения, cin пока ввод не станет действительным. И вам нужно убедиться, что cin это даже успешное чтение значения, прежде чем выполнять проверку диапазона для этого значения.

Я бы предложил выполнить проверку чтения в отдельной функции, например:

 #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 << "ntError: Invalid input!n" << endl;
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
        }
        else if (value < 0)
        {
            cout << "ntError: Value must be greater than 0!n" << endl;
        }
        else if (value >= maxValue)
        {
            cout << "ntError: 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";
  

Ответ №2:

Вы можете использовать несколько циклов while, по одному для каждого ввода.

 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;
  

Комментарии:

1. Вы не подтверждаете, что cin >> ... это успешно

2. В случае cin >> ... сбоя cin вводится состояние ошибки, которое вы не очищаете (т. Е. Если пользователь вводит нечисловой ввод), что приведет к бесконечному циклу.

3. И, что еще лучше, поместите эти несколько циклов в несколько функций, по одному для каждого цикла. Затем ищите сходства и, возможно, консолидируйте функции.