C ++ Использование cin.fail (), cin.clear () - у меня бесконечный цикл и я не знаю почему

0

Можете ли вы не использовать cin, а затем cin.fail() в той же строке, как это? Есть ли более чистый или более стандартный способ проверки этого типа ошибок при вводе? --perhaps не использует do-while.

do {
     cin.clear();
     cout << "\nPlease enter the size of the array (1-10): ";
} while (cin >> array_size && array_size <= 1 || array_size >= 10 || cin.fail());

Это работает:

do {
    cout << "Please input #: ";
    if (cin.fail()){
        cin.clear();
        cin.ignore(80, '\n');
    }
    cin >> kids_total;
} while (cin.fail() || kids_total <= 0);
  • 0
    переместить Cin внутри цикла
  • 0
    @ta.speot.is:ta.speot.is: Это не имеет ничего общего с приоритетом оператора.
Показать ещё 1 комментарий
Теги:

1 ответ

0
Лучший ответ
cin >> array_size && array_size <= 1 || array_size >= 10 || cin.fail()

Скажем, вы получили письмо следующего в cin, cin >> array_size оценивает false так && короткого замыкания evalusation пропускает array_size <= 1 для теста:

  • array_size >= 10: может быть неинициализированное чтение памяти ==> неопределенное поведение, иначе предположительно false
  • cin.fail() - определенно true

... если нет неопределенного поведения - и, возможно, даже тогда - цикл будет продолжаться, не удалив письмо из cin, только для немедленного сбоя.

Проверьте cin.ignore на способ удаления ввода, который не прошел синтаксический анализ, или используйте std::getline(std::cin, my_string), std::istringstream iss(my_string); if (iss >> array_size std::istringstream iss(my_string); if (iss >> array_size и т.д. для того, чтобы гарантировать, что вся строка отброшена на плохой вход....


Для сравнения, это довольно надежный и ИМХО интуитивно понятный, если многословный. Если вы делаете это несколько раз, просто создайте функцию....

while (true)
{
    std::cout << "Please input #: ";
    if (std::cin >> kids_total)
    {
        if (kids_total > 0)
            break;
        std::cout << "Value must be > 0, please try again.\n";
    }
    else if (std::cin.eof())
    {
        // rare for keyboard input - e.g. ^D on UNIX/Linux, ^Z Windows
        // can happen with pipes/redirects - e.g. echo 10 20 | ./my_app
        std::cerr << "expected value for kids_total but encountered end of input\n";
        exit(EXIT_FAILURE);
    }
    else
    {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
}
  • 0
    Оказывается, следующий код работает отлично. Но по какой-то причине в операторе if, если я поставлю cin.ignore перед cin.clear, произойдет бесконечный цикл. Почему ты так думаешь? Кроме того, если я не использую оператор if и не помещаю cin.ignore перед оператором cout, он не будет напечатан, и до выхода из цикла будет около 6 или 7 cin. Код не форматировал, поэтому я поместил его в свой первый пост.
  • 0
    «Произойдет бесконечный цикл. Почему вы думаете, что это?» - потому что, когда поток остается в состоянии ошибки - т.е. не очищен - дальнейшие операции, включая ignore , просто пропускаются. Я добавлю, как я реализую цикл в своем ответе, чтобы вы могли сравнить с тем, что вы в конечном итоге ....
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню