Несколько блоков catch в C++
В одном try может произойти сбой разного
типа. Если указать в catch только один
тип, остальные исключения не перехватятся
и программа остановится.
Решение - несколько блоков catch подряд.
Среда выполнения выбирает первый блок, тип
которого подходит к возникшему исключению:
int main() {
try {
// код, который может сорваться
} catch (const std::invalid_argument& e) {
// ошибка формата
} catch (const std::runtime_error& e) {
// нарушение правила
}
return 0;
}
Пусть функция делит два числа, переданные строками. Ошибка преобразования и деление на ноль обрабатываются разными сообщениями:
void divideStrings(const std::string& a, const std::string& b) {
try {
int x = std::stoi(a);
int y = std::stoi(b);
if (y == 0) {
throw std::runtime_error("zero");
}
std::cout << x / y << "\n";
} catch (const std::invalid_argument& e) {
std::cout << "not a number\n";
} catch (const std::runtime_error& e) {
std::cout << "division by zero\n";
}
}
int main() {
divideStrings("10", "0");
divideStrings("10", "two");
return 0;
}
Более конкретный catch ставят выше общего.
Если сначала написать широкий тип вроде
std::exception, до узких типов выполнение
может не дойти. В начальных задачах достаточно
перечислять нужные типы по одному.
int main() {
std::vector<int> vec = {1, 2, 3};
std::string indexStr = "x";
try {
int i = std::stoi(indexStr);
std::cout << vec.at(i) << "\n";
} catch (const std::invalid_argument& e) {
std::cout << "bad index text\n";
} catch (const std::out_of_range& e) {
std::cout << "bad index value\n";
}
return 0;
}
Даны строки left и right.
В try преобразуйте обе через std::stoi
и выведите частное первого на второе.
Для std::invalid_argument выведите
"parse", для std::runtime_error
при нулевом делителе выведите "zero".
Дан вектор и строка с индексом. В одном try
получите индекс и элемент вектора. Отдельными
catch обработайте std::invalid_argument
и std::out_of_range разными сообщениями
на английском.