Хотя цикл не работает, когда пользователь вводит буквы вместо целых чисел? [Дубликат]

Обновление. Теперь вы можете экспортировать отчеты аналитики в виде CSV из консоли Firebase, щелкнув опцию «Загрузить CSV» в меню переполнения..


. Тем временем вы действительно должны дать BigQuery другой смотреть. цена очень разумна и существует свободный уровень запросов 1 ТБ / мес.

Стив Ганем

Менеджер продуктов, Firebase Analytics

17
задан Brian Tompsett - 汤莱恩 19 November 2015 в 15:30
поделиться

4 ответа

Причина, по которой программа переходит в бесконечный цикл, связана с тем, что флаг неудачного ввода std::cin установлен из-за сбоя ввода. Необходимо сделать это, чтобы очистить этот флаг и отбросить плохой вход из входного буфера.

//executes loop if the input fails (e.g., no characters were read)
while (std::cout << "Enter a number" && !(std::cin >> num)) {
    std::cin.clear(); //clear bad input flag
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard input
    std::cout << "Invalid input; please re-enter.\n";
}

См. C ++ FAQ для этого и другие примеры, включая добавление минимальный и / или максимальный в условие.

Другим способом было бы получить ввод как строку и преобразовать его в целое число с std::stoi или другим методом, который позволяет проверять преобразование.

37
ответ дан chris 18 August 2018 в 16:23
поделиться
  • 1
    Я сделал некоторые исследования, прежде чем спрашивать здесь. Я увидел, что они положили cin.ignore (1000, '\n'); что это делает? Также! (Cin & gt; & gt; num) возвращает логическое значение? я не знал, что – Zik 27 April 2012 в 12:42
  • 2
    спасибо за сайт – Zik 27 April 2012 в 12:48
  • 3
    @Marvin, cin.ignore (1000, '\n') игнорирует / отбрасывает символы во входном буфере до тех пор, пока не будет отброшена ни одна из 1000, или столбец новой строки, в зависимости от того, что наступит раньше. Это хороший способ избавиться от линии. В парашютном примере вы увидите максимальный размер потока вместо 1000, чтобы учесть длину максимальной длины. Я использую cin.sync(), потому что, когда я это делаю, я хочу быть на равных с пользователем (еще не прочитал следующую строку), поэтому я отбрасываю все. Наконец, cin имеет operator void *, поэтому он cann преобразуется в bool. – chris 27 April 2012 в 12:48
  • 4
    но как проверяется цикл while? (cin & gt; num)? – Zik 27 April 2012 в 13:12
  • 5
    @Marvin, cin >> num терпит неудачу, если пользователь набирает, скажем 'a', когда он ожидал int. Он предоставляет оператор преобразования, чтобы он неявно преобразовывался в void *. Если cin находится в плохом состоянии, он вернет NULL. Если нет, он вернет объект. Затем это можно сделать и преобразовать в bool: true, если не NULL, false, если NULL. Затем цикл может использовать это для оценки выражения bool, в котором он нуждается. – chris 27 April 2012 в 13:15

Ответ на главный проголосовавший ответ очень хорошо удовлетворяет решению.

В дополнение к этому ответу это может помочь визуализировать то, что происходит немного лучше:

int main()

    int input = 1;//set to 1 for illustrative purposes
    bool cinState = false;
    string test = "\0";
    while(input != -1){//enter -1 to exit
        cout << "Please input (a) character(s): ";//input a character here as a test
        cin >> input; //attempting to input a character to an int variable will cause cin to fail
        cout << "input: " << input << endl;//input has changed from 1 to 0
        cinState = cin;//cin is in bad state, returns false
        cout << "cinState: " << cinState << endl;
        cin.clear();//bad state flag cleared
        cinState = cin;//cin now returns true and will input to a variable
        cout << "cinState: " << cinState << endl;
        cout << "Please enter character(s): ";
        cin >> test;//remaining text in buffer is dumped here. cin will not pause if there is any text left in the buffer.
        cout << "test: " << test << endl;
    }
    return 0;    
}

Сбрасывание текста в буфере переменной не особенно полезен, однако помогает визуализировать, почему cin.ignore() необходим.

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

5
ответ дан Ganesh Kamath - 'Code Frenzy' 18 August 2018 в 16:23
поделиться

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

-2
ответ дан user 18 August 2018 в 16:23
поделиться

Вы можете проверить это через значение ASCII, если значение ascii s между 65 t0 90 или 97 to 122 будет символом.

-2
ответ дан vikky 18 August 2018 в 16:23
поделиться
  • 1
    Откуда вы знаете, что система использует ASCII? – Toby Speight 31 May 2018 в 16:07
Другие вопросы по тегам:

Похожие вопросы: