Странное поведение при чтении int из STDIN

Предположим, у нас есть меню, которое предоставляет пользователю несколько опций:

Welcome:
1) Do something
2) Do something else
3) Do something cool
4) Quit

Пользователь может нажать 1 - 4, а затем клавишу ввода. Программа выполняет эту операцию, а затем возвращает меню пользователю. Недопустимая опция должна просто снова отображать меню.

У меня есть следующий метод main():

int main()
{
    while (true)
        switch (menu())
        {
            case 1:
                doSomething();
                break;
            case 2:
                doSomethingElse();
                break;
            case 3:
                doSomethingCool();
                break;
            case 4:
                return 0;
            default:
                continue;
        }
}

и следующий menu():

int menu()
{
  cout << "Welcome:" << endl
       << "1: Do something" << endl
       << "2: Do something else" << endl
       << "3: Do something cool" << endl
       << "4: Quit" << endl;

  int result = 0;
  scanf("%d", &result);
  return result;
}

Ввод числовых типов работает отлично. Ввод от 1 до 4 приводит к тому, что программа выполняет желаемое действие, после чего снова отображается меню. Ввод числа за пределами этого диапазона, например -1 или 12, снова отобразит меню, как и ожидалось.

Тем не менее, ввод чего-то вроде 'q' приведет к тому, что меню будет отображаться снова и снова бесконечно, даже не останавливаясь, чтобы получить пользовательский ввод.

Я не понимаю, как это могло произойти. Ясно, что menu()вызывается, поскольку меню отображается снова и снова, однако scanf()является частью menu(), поэтому я не не понимаю, как программа попадает в это состояние ошибки, когда пользователю не предлагается ввести свои данные.

Первоначально у меня был cin >> результат, который делал то же самое.

Редактировать: Кажется, есть вопрос, связанный с , однако исходный код исчез из pastebin, а один из ответов ссылается на статью , что, по-видимому, когда-то объясняло, почему это происходит, но теперь является мертвой ссылкой. Может быть, кто-то может ответить, почему это происходит, а не ссылаться? :)

Редактировать: Используя этот пример , вот как я решил проблему:

int getNumericalInput()
{
    string input = "";
    int result;

    while (true)
    {
        getline(cin, input);

        stringstream sStr(input);
        if (sStr >> result)
            return result;

        cout << "Invalid Input. Try again: ";
    }
}

и я просто заменил

int result = 0;
scanf("%d", &result);

на

int result = getNumericalInput();

5
задан Community 23 May 2017 в 12:33
поделиться