In C++, the try-catch
block is used to catch and handle exceptions (errors) that may occur during the execution of a program.
An exception is an unexpected event that interrupts the normal flow of the program. The purpose of the try-catch block is to allow the program to respond to errors in a controlled manner, rather than terminating abruptly.
Basic Structure
The basic structure of try-catch
is as follows:
try {
// Code that may throw an exception
}
catch (const std::exception& e) {
// Code to handle the exception
}
- The try block contains the code that might generate an exception.
- The catch block captures the exception and allows code to execute to manage it.
Basic Example
Let’s see it with a simple example, where we attempt to divide two numbers and handle a possible division by zero:
#include <iostream>
#include <stdexcept>
int main() {
try {
int divisor = 0;
if (divisor == 0) {
throw std::runtime_error("Error: Division by zero not allowed.");
}
int result = 10 / divisor;
}
catch (const std::runtime_error& e) {
std::cout << e.what() << std::endl; // Displays the exception message
}
return 0;
}
In this example, we throw a std::runtime_error
when divisor
is zero. The catch
block captures this exception and prints an informative message.
Capturing Multiple Exceptions
You can have multiple catch
blocks to handle different types of exceptions specifically:
#include <iostream>
#include <stdexcept>
int main() {
try {
// Code that may throw exceptions
throw std::logic_error("Logical error");
}
catch (const std::logic_error& e) {
std::cout << "Caught: " << e.what() << std::endl;
}
catch (const std::runtime_error& e) {
std::cout << "Caught: " << e.what() << std::endl;
}
catch (...) {
std::cout << "Unknown error" << std::endl;
}
return 0;
}
In this example:
std::logic_error
andstd::runtime_error
are caught in specificcatch
blocks.
General catch
Sometimes, it is useful to have a catch
block that can handle any type of exception. This is achieved using the catch(...)
syntax, which captures any exception regardless of its type.
try {
throw 10.5;
} catch (...) {
std::cerr << "An exception has been caught." << std::endl;
}
Using catch(...)
is a way to ensure that any exception, regardless of its type, is handled.
Practical Examples
Handling Exceptions in I/O Operations
In this example, we use try-catch
to handle exceptions related to reading a file.
We capture two types of exceptions: std::ios_base::failure
if there is an I/O error, and std::exception
for other general issues.
#include <iostream>
#include <fstream>
#include <stdexcept>
int main() {
try {
std::ifstream file("file.txt");
if (!file) {
throw std::ios_base::failure("Error: Cannot open the file.");
}
std::string line;
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
}
catch (const std::ios_base::failure& e) {
std::cout << "File error: " << e.what() << std::endl;
}
catch (const std::exception& e) {
std::cout << "General error: " << e.what() << std::endl;
}
return 0;
}
This code attempts to read a file, and if an error occurs while opening it or during reading, it captures the exception and displays a message in the console.