Language: EN

cpp-bloque-try-catch

The Try-Catch Block in C++

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
}

Where:

  • The try block contains the code that might generate an exception.
  • The catch block captures the exception and allows executing code to manage it.

Basic Example

Let’s see it with a simple example, where we try 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 << "Captured: " << e.what() << std::endl;
    }
    catch (const std::runtime_error& e) {
        std::cout << "Captured: " << e.what() << std::endl;
    }
    catch (...) {
        std::cout << "Unknown error" << std::endl;
    }
    return 0;
}

In this example:

  • std::logic_error and std::runtime_error are captured in specific catch 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, no matter 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.