Перекомпоновка, если ввод неверен в C ++ - PullRequest
1 голос
/ 17 апреля 2020

Я знаю, что это, вероятно, довольно простой вопрос c, но я в тупике. Я пытаюсь предложить пользователю ввести 1, 2, 3 или 4. И, если они не вводят правильный выбор, спросить их снова. Но всякий раз, когда я выполняю программу и ввожу неверный результат, она просто зацикливается, не останавливаясь для пользовательского ввода, печатая первую строку cout снова и снова. Как я могу это исправить? Является ли вызов функции изнутри сам по себе плохой идеей? Нужно ли как-нибудь очистить Син?

int hallwayask()
{
    int input;
    cout << "1: Door 1 \n2: Door 2 \n3: Door 3 \n4: Door 4\n";
    cin >> input;
    if (cin.good())
    {
        switch(input)
        {
            case 1:
                room1();
                break;
            case 2:
                room2();
                break;
            case 3:
                room3();
                break;
            case 4:
                room4();
                break;
            default:
                cout << "Please enter a valid number." << endl;
                break;
        }
    }
    else
    {
        hallwayask();
    }
}

Ответы [ 3 ]

1 голос
/ 17 апреля 2020

Попробуйте этот фрагмент. Это говорит само за себя, плюс вам не нужно вызывать эту функцию снова и снова, делая логику c проще и программу быстрее.

int hallwayask()
{
    int input;

//Write the "do{" here if you wish these
//options to be shown again and again when
//user gives invalid input

    cout << "1: Door 1 \n2: Door 2 \n3: Door 3 \n4: Door 4\n";

    do
    { //this is the "do{" I referred to earlier
        cin >> input;

        switch (input)
        {

            case 1:
                room1();
                break;

            case 2:
                room2();
                break;

            case 3:
                room3();
                break;

            case 4:
                room4();
                break;

            default:
                cout << "Please enter a valid number: " << endl;
                break;
        }
    } while ((input != 1) && (input != 2) && (input != 3) && (input != 4));

    return (input); //the correct input is returned to the calling function

}

По поводу вашего вопроса - Нет, вызов одной и той же функции из Само по себе (то, что мы называем «рекурсивным вызовом») не так уж и плохо, если вы знаете, что цепочка вызовов завершится в определенный момент. Очень распространенный пример - рекурсивный алгоритм поиска факториала целого числа. Мы не используем рекурсивные функции, когда конечная точка может быть не достигнута, как, например, в этом случае; Что делать, если пользователь продолжает вводить неверные данные? Вы просто заполните свой стек, и будет sh, если память заполнится. (Потому что каждый рекурсивный вызов функции помещает текущий экземпляр функции в стек)

0 голосов
/ 17 апреля 2020

Проблема в том, что после сбоя cin вы не clear() выводите состояние ошибки потока, поэтому operator>> продолжает сбой, а good() продолжает возвращать false, поэтому вы застряли в бесконечной л oop.

Вам необходимо проверить ввод пользователя перед его использованием и очистить ввод, когда он недействителен, чтобы не перечитывать его.

Кроме того, вы должны использовать итеративную l oop вместо рекурсивной l oop.

Попробуйте вместо этого:

#include <limits>

int hallwayask()
{
    int input;
    cout << "1: Door 1 \n2: Door 2 \n3: Door 3 \n4: Door 4\n";
    do
    {
        if (!(cin >> input))
        {
            cout << "Invalid input! Please enter an integer only." << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            continue;
        }

        if ((input >= 1) && (input <= 4))
            break;

        cout << "Please enter a valid number 1-4." << endl;
    }
    while (true);

    switch (input)
    {
        case 1:
            room1();
            break;
        case 2:
            room2();
            break;
        case 3:
            room3();
            break;
        case 4:
            room4();
            break;
    }
}
0 голосов
/ 17 апреля 2020

Попробуйте:

#include <iostream>
using namespace std;
int hallwayask();

int main()
{
    hallwayask();

}

int hallwayask()
{
    int input;
    bool flag = true;
    while (flag)
    {
        cout << "1: Door 1 \n2: Door 2 \n3: Door 3 \n4: Door 4\n";
        cin >> input;
        if (cin.good())
        {
            switch(input)
            {
                case 1:
                    cout << room1();
                    flag = false;
                    break;
                case 2:
                    cout << room2();
                    flag = false;
                    break;
                case 3:
                    cout << room3();
                    flag = false;
                    break;
                case 4:
                    cout << room4();
                    flag = false;
                    break;
                default:
                    cout << "Please enter a valid number." << endl;
                    break;
            }
        }
        else
        {
            cout << "Invalid input, enter an int" << endl;
            cin.clear();
            cin.ignore(INT8_MAX, '\n');
        }
    }
}

Я устанавливаю флаг bool в значение true, и хотя это правда, он будет go включаться вечно, но как только пользователь введет правильное число (1-2- 3-4) Я устанавливаю флаг в ложь, поэтому он остановится.

Подумайте об этом так: пока true, сделайте этот блок кода, если false остановите. Таким образом, время будет длиться вечно, если это правда, но как только я введу 1-2-3-4, я остановлю время, пока l oop.

Я уверен, что есть другие способы сделать это; Я всегда полагался на флаг true / false для этого, но доступны и другие варианты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...