-
Hajipur, Bihar, 844101
In programming, things don’t always go as planned. A file might fail to open, a variable might contain an unexpected value, or the program might attempt to divide by zero. These are called exceptions, and they interrupt the normal flow of a program.
In C++, exception handling allows a program to detect and handle such problems gracefully instead of crashing. It separates error-handling logic from regular code, making programs more robust and easier to maintain.
An exception is an event that occurs during the execution of a program that disrupts its normal flow. When an exception occurs, it is “thrown,” and the program looks for code that can “catch” and handle it.
C++ provides three main keywords for exception handling:
try – Defines a block of code to test for errors.
throw – Signals that an error has occurred.
catch – Defines a block of code that handles the error.
Here’s the general structure:
try {
// Code that may cause an exception
}
catch (type exceptionName) {
// Code to handle the exception
}
If an error occurs inside the try block, control is immediately transferred to the matching catch block.
#include <iostream>
using namespace std;
int main() {
int a = 10, b = 0;
try {
if (b == 0)
throw "Division by zero error!";
cout << "Result: " << a / b;
}
catch (const char* msg) {
cout << "Exception caught: " << msg << endl;
}
return 0;
}
Output:
Exception caught: Division by zero error!
In this example, instead of crashing, the program safely reports the issue.
The throw keyword is used to raise an exception manually when something unexpected happens. You can throw different types of data such as integers, strings, or custom exception classes.
throw 404; // throwing an integer
throw "Error occurred"; // throwing a string
throw exceptionObject; // throwing an object
The type of value thrown determines which catch block will handle it.
The catch block is used to handle exceptions. Multiple catch blocks can follow a single try block to handle different types of errors.
try {
throw 10;
}
catch (int e) {
cout << "Caught an integer exception: " << e;
}
catch (...) {
cout << "Caught an unknown exception.";
}
The catch(...) block acts as a general handler for any exception type not specifically caught.
You can have multiple catch blocks to handle different kinds of exceptions separately.
#include <iostream>
using namespace std;
int main() {
try {
int option = 2;
if (option == 1)
throw 10;
else if (option == 2)
throw "Invalid choice!";
}
catch (int e) {
cout << "Integer exception caught: " << e;
}
catch (const char* msg) {
cout << "String exception caught: " << msg;
}
return 0;
}
The ellipsis catch block (catch(...)) can be used when you’re not sure what type of exception might occur.
try {
throw 3.14;
}
catch (...) {
cout << "Caught an unknown exception.";
}
This is useful for catching unexpected errors to prevent a crash.
Exceptions can be thrown inside functions and caught where the function is called. This makes your code modular and reusable.
#include <iostream>
using namespace std;
void divide(int a, int b) {
if (b == 0)
throw "Cannot divide by zero!";
cout << "Result: " << a / b << endl;
}
int main() {
try {
divide(10, 0);
}
catch (const char* msg) {
cout << "Error: " << msg << endl;
}
return 0;
}
C++ provides a built-in hierarchy of standard exception classes inside the <exception> header.
#include <iostream>
#include <exception>
using namespace std;
int main() {
try {
throw runtime_error("Runtime error occurred");
}
catch (exception &e) {
cout << "Caught exception: " << e.what() << endl;
}
return 0;
}
The what() function provides a human-readable description of the error.
You can create your own exception class for specific situations.
#include <iostream>
#include <exception>
using namespace std;
class MyException : public exception {
public:
const char* what() const throw() {
return "Custom Exception: Invalid operation!";
}
};
int main() {
try {
throw MyException();
}
catch (MyException &e) {
cout << e.what() << endl;
}
return 0;
}
This approach is useful for large applications with unique error types.
Throwing exceptions but forgetting to catch them.
Catching by value instead of by reference, which may cause object slicing.
Using exceptions for normal control flow (should be avoided).
Ignoring exceptions, which can lead to program crashes.
Not including descriptive error messages.
Keeps error-handling separate from main logic.
Makes programs more stable and user-friendly.
Provides a cleaner way to handle unexpected runtime problems.
Encourages modular code through function-level handling.
C++ exceptions provide a structured way to detect and handle runtime errors gracefully. By using try, throw, and catch, developers can prevent crashes and maintain control when unexpected events occur. Exception handling improves code clarity, reliability, and user experience, especially in large or complex programs.
Write a C++ program that throws and catches a division-by-zero exception using try, throw, and catch.
Create a program that throws different types of exceptions (int, string, float) and uses multiple catch blocks to handle each type.
Write a function that reads a number from the user and throws an exception if the number is negative. Catch and display a custom message.
Build a program that throws an exception when trying to open a file that does not exist. Handle it gracefully.
Create a custom exception class that displays a message when an invalid input is entered by the user.
Write a C++ program that uses catch(...) to handle unknown exception types.
Make a function that throws an exception if the array index accessed is out of range. Catch and display an appropriate message.
Use a try block inside another try block (nested try-catch) to demonstrate how exception handling works in nested scopes.
Write a program using the standard runtime_error class to display a custom error message when invalid data is processed.
Implement a program that simulates a simple calculator. Throw exceptions for division by zero or invalid operators and handle them in catch blocks.