Краткое содержание
Ввод является границей, через которую мир входит в программу, а мир не соблюдает спецификаций. Этот урок учит читать, не доверяя: читать целые строки с помощью std::getline и избегать пустой строки, которая появляется, если смешать его с >>; опрашивать состояние потока и различать с его помощью три ситуации, которые урок Ввод, вывод и ошибки видел только смешанными (неверное значение, число, которое не помещается, и конец данных); восстанавливаться после неудачного чтения с помощью clear и ignore; и, как самый надёжный способ, читать каждое значение как текст и преобразовывать его с помощью std::from_chars, принимая его, только если преобразование поглотило весь текст. Урок завершается функцией readInt с контрактом, которую остальная часть курса может использовать повторно.
Цели обучения
- Читать целые строки с помощью
std::getline, объяснять, почемуgetline, следующий за чтением через>>, возвращает пустую строку, и избегать этого с помощьюstd::ws. - Опрашивать состояние потока после чтения с помощью
fail()иeof()и различать с его помощью неверное значение, число, которое не помещается в свой тип, и конец ввода. - Писать цикл чтения, который восстанавливается после неверного ввода с помощью
clearиignoreи завершается, если ввод кончился. - Проверять корректность числа, прочитанного как текст, с помощью
std::from_chars, требуя, чтобы не было ошибки и чтобы строка была поглощена целиком, и выносить эту работу в функции с контрактом.
Снова граница
Урок Ввод, вывод и ошибки установил три факта о std::cin >> n: чтение останавливается, не поглощая его, на первом символе, который не может продолжить число; если не удаётся прочитать ни одного, поток переходит в состояние ошибки и всякое последующее чтение ничего не делает; а if (std::cin) позволяет узнать, не случилась ли неудача. Урок Циклы добавил, что условие while (std::cin >> value) завершает цикл как тогда, когда ввод кончается, так и тогда, когда приходит неверное значение. Однако с этими средствами программа обнаруживает, что что-то пошло не так, но не знает, что именно, и не может сделать ничего, кроме как сдаться.
Этот урок исходит из принципа проектирования, принципа защитного программирования на границе: всякое входящее значение проверяется до того, как его используют, и программа, которая его проверяет, отличает неверное значение, допускающее исправление (запросить его снова, пропустить, сообщить о нём), от конца данных, который исправления не допускает. Если это так, нужны три вещи: прочитать значение так, как оно было записано, то есть строку; знать, почему чтение не удалось; и вернуть потоку способность читать.
Загрузка содержимого…