Программирование. Принципы и практика использования C++ Исправленное издание, стр. 66
int main()try { vector<int> v; // вектор целых чисел int x; while (cin>>x) v.push_back(x); // записываем значения for (int i = 0; i<=v.size(); ++i) // выводим значения cout << "v[" << i <<"] == " << v[i] << endl;} catch (out_of_range) { cerr << "Ой! Ошибка диапазона \n"; return 1; } catch (...) { // перехват всех других исключений cerr << "Исключение: что-то не так \n"; return 2;}Обратите внимание на то, что ошибка диапазона на самом деле является частным случаем ошибки, связанной с аргументами, которую мы обсудили в разделе 5.5.2. Не доверяя себе, мы поручили проверку диапазона индексов вектора самой операции доступа по индексу. По очевидным причинам оператор доступа по индексу (
vector::operator[]5.6.3. Неправильный ввод
Обсуждение действий, которые следует предпринять при неправильном вводе данных, мы отложим до раздела 10.6. Пока лишь отметим, что при обнаружении ошибки ввода используются те же самые методы и механизмы языка программирования, что и при обработке ошибок, связанных с неправильными аргументами и выходом за пределы допустимого диапазона. Здесь мы лишь покажем, как поступать, если операции ввода достигли цели.
Рассмотрим фрагмент кода, в котором вводится число с плавающей точкой.
double d = 0;cin >> d;Мы можем проверить, успешной ли оказалась последняя операция, подвергнув проверке поток
cinif (cin) { // все хорошо, и мы можем считывать данные дальше}else { // последнее считывание не было выполнено, // поэтому следует что-то сделать}Существует несколько возможных причин сбоя при вводе данных. Одна из них — тип данных, которые мы пытаемся считать, — отличается от типа
doubledouble some_function(){ double d = 0; cin >> d; if (!cin) error("невозможно считать число double в 'some_function()'"); // делаем что-то полезное}Строку, переданную функции
error()error()error()В стандартной библиотеке определено несколько типов исключений, таких как
out_of_rangevectorruntime_errorИтак, нашу простую функцию
error()void error(string s){ throw runtime_error(s);}Когда нам потребуется поработать с исключением
runtime_errorruntime_errormain()int main()try { // наша программа return 0; // 0 означает успех}catch (runtime_error& e) { cerr << "runtime error: " << e.what() << '\n'; keep_window_open(); return 1; // 1 означает сбой}Вызов
e.what()runtime_errorСимвол
&catch(runtime_error& e) {означает, что мы хотим передать исключение по ссылке. Пожалуйста, пока рассматривайте это выражение просто как техническую подробность. В разделах 8.5.4–8.5.6 мы объясним, что означает передача сущности по ссылке.
Обратите внимание на то, что для выдачи сообщений об ошибках мы использовали поток
cerrcoutcerrcoutcerrcerrcerr