Программирование. Принципы и практика использования C++ Исправленное издание, стр. 145
int n = 0;while (true) { cin >> n; if (cin) { // мы ввели целое число; теперь проверим его if (1<=n && n<=10) break; cout << "Извините, " << n << " выходит за пределы интервала [1:10]; попробуйте еще \n"; } else if (cin.fail()) { // обнаружено нечто, что является // целым числом cin.clear(); // возвращаем поток в состояние good(); // мы хотим взглянуть на символы cout << "Извините, это не число; попробуйте еще раз \n"; char ch; while (cin>>ch && !isdigit(ch)); // отбрасываем не цифры if (!cin) error(" ввода нет "); // цифры не обнаружены: // прекратить cin.unget(); // возвращаем цифру назад, // чтобы можно было считать число } else { error(" ввода нет "); // состояние eof или bad: прекратить }}// если мы добрались до этой точки, значит, число n лежит// в диапазоне [1:10]
• Считывание значения.
• Предложение к вводу.
• Вывод сообщений об ошибках.
• Пропуск “плохих” входных символов.
• Проверка диапазона входных чисел.
void skip_to_int(){ if (cin.fail()) { // обнаружено нечто, что является целым числом cin.clear(); // возвращаем поток в состояние good(); // мы хотим взглянуть на символы char ch; while (cin>>ch){ // отбрасываем не цифры if (isdigit(ch) || ch == '-') cin.unget(); // возвращаем цифру назад, // чтобы можно было считать число } } } error(" ввода нет "); // состояние eof или bad: прекратить}Имея вспомогательную функцию
skip_to_int()cout << "Пожалуйста, введите целое число от 1 до 10:\n";int n = 0;while (true) { if (cin>>n) { // мы ввели целое число; теперь проверим его if (1<=n && n<=10) break; cout << "Извините, " << n << " выходит за пределы интервала [1:10]; попробуйте еще раз.\n"; } else { cout << "Извините, это не число; попробуйте еще раз.\n"; skip_to_int(); }}// если мы добрались до этой точки, значит, число n лежит// в диапазоне [1:10]Этот код лучше, но остается слишком длинным и запутанным для того, чтобы много раз применять его в программе. Мы никогда не добьемся желаемого результата, разве что после (слишком) долгой проверки. Какие операции мы бы хотели иметь на самом деле? Один из разумных ответов звучит так: “Нам нужны две функции: одна должна считывать любое число типа int, а другая — целое число из заданного диапазона”.
int get_int(); // считывает число типа int из потока cinint get_int(int low, int high); // считывает из потока cin число int, // находящееся в диапазоне [low:high]Если бы у нас были эти функции, то мы могли бы, по крайней мере, использовать их просто и правильно. Их несложно написать.
int get_int(){ int n = 0; while (true) { if (cin >> n) return n; cout << "Извините, это не число; попробуйте еще раз \n"; skip_to_int(); }} В принципе функция
get_int()get_int()get_int()