Exceptions and Files
Exceptions and Files
Fundamentals
By Engr. Sher Mohammad
Exception Handling
• An exception is an unexpected event that occurs during program execution. For example,
• divide_by_zero = 7 / 0;
• The above code causes an exception as it is not possible to divide a number by 0.
• The process of handling these types of errors in C++ is known as exception handling.
• In C++, we handle exceptions with the help of the try and catch blocks, along with the throw keyword.
• Note: The throw statement is not compulsory, especially if we use standard C++ exceptions.
Syntax for Exception Handling in C++
• The basic syntax for exception handling in C++ is given below:
• try {
• // code that may raise an exception
• throw argument;
• }
• catch (exception) {
• // code to handle exception
• }
• Here, we have placed the code that might generate an exception inside the try block. Every try block is
followed by the catch block.
• When an exception occurs, the throw statement throws an exception, which is caught by the catch block.
• The catch block cannot be used without the try block.
Example 1: C++ Exception Handling
• // program to divide two numbers • try {
• // throws an exception when the divisor is 0 • // throw an exception if denominator is 0
• if (denominator == 0)
• #include <iostream> • throw 0;
• using namespace std; • // not executed if denominator is 0
• divide = numerator / denominator;
• int main() { • cout << numerator << " / " <<
denominator << " = " << divide << endl;
• double numerator, denominator, divide; • }
• catch (int num_exception) {
• cout << "Enter numerator: "; • cout << "Error: Cannot divide by " <<
• num_exception << endl;
cin >> numerator;
• }
• • return 0;
cout << "Enter denominator: ";
• • }
cin >> denominator;
Output 1 Explanation:
• The above program divides two numbers and
• Enter numerator: 72 displays the result. But an exception occurs if the
• Enter denominator: 0 denominator is 0.
• To handle the exception, we have put the code
• Error: Cannot divide by 0 divide = numerator / denominator; inside the try
block. Now, when an exception occurs, the rest of
the code inside the try block is skipped.
Output 2 • The catch block catches the thrown exception and
executes the statements inside it.
• Enter numerator: 72 • If none of the statements in the try block generates
• Enter denominator: 3 an exception, the catch block is skipped.
• 72 / 3 = 24
• Notice that we have thrown the int literal 0 with the code throw 0;.
• We can throw any literal or variable or class, depending on the situation and depending on what we
want to execute inside the catch block.
• The catch parameter int num_exception takes the value passed by the throw statement i.e. the literal
0.
Catching All Types of Exceptions
• In exception handling, it is important that we know the types of exceptions that can occur due to
the code in our try statement.
• This is so that we can use the appropriate catch parameters. Otherwise, the try...catch statements
might not work properly.
• If we do not know the types of exceptions that can occur in our try block, then we can use the
ellipsis symbol ... as our catch parameter.
• try {
• // code
• }
• catch (...) {
• // code
• }
Example:
• try {
• int age = 15;
• if (age >= 18) {
• cout << "Access granted - you are old enough.";
• } else {
• throw 505;
• }
• }
• catch (...) { Output:
• cout << "Access denied - You must be at least 18 years old.\n"; Access denied - You must
be at least 18 years old.
• }
C++ Multiple catch Statements
• n C++, we can use multiple catch statements for different kinds of exceptions that can
result from a single block of code.
• try {
• // code
• }
• catch (exception1) {
• // code
• }
• catch (exception2) {
• // code
• }
• catch (...) {
• // code
• }
Explanation
• Here, our program catches exception1 if that exception occurs. If not, it will catch
exception2 if it occurs.
• If there is an error that is neither exception1 nor exception2, then the code inside of
catch (...) { } is executed.
Notes:
• catch (...) {} should always be the final block in our try...catch statement. This is
because this block catches all possible exceptions and acts as the default catch block.
• It is not compulsory to include the default catch block in our code.
Example 2: C++ Multiple catch Statements
• This program divides two numbers and stores the result in an array
element. There are two possible exceptions that can occur in this
program:
• If the array is out of bounds i.e. if the index of the array is greater than
the size of the array
• If a number is divided by 0
• These exceptions are caught in multiple catch statements.
Program
int main() { • // catch "Array out of bounds" exception
• double numerator, denominator, arr[4] = {0.0, 0.0, 0.0, 0.0}; • catch (const char* msg) {
• cout << msg << endl;
• int index;
• }
• cout << "Enter array index: ";
• cin >> index; • // catch "Divide by 0" exception
• catch (int num) {
• try {
• cout << "Error: Cannot divide by " << num << endl;
• // throw exception if array out of bounds • }
• if (index >= 4)
• // catch any other exception
• throw "Error: Array out of bounds!";
• catch (...) {
• // not executed if array is out of bounds • cout << "Unexpected exception!" << endl;
• cout << "Enter numerator: "; • }
•
• cin >> numerator;
• return 0;
• cout << "Enter denominator: "; • }
• cin >> denominator;
• // throw exception if denominator is 0
• if (denominator == 0)
• throw 0;
• // not executed if denominator is 0
• arr[index] = numerator / denominator;
• cout << arr[index] << endl;
• }
Outputs
• Output 1
• In this case, index is 5. So, we throw a string literal "Error: Array out
of bounds!". This exception is caught by the first catch block.
• Notice the catch parameter const char* msg. This indicates that the
catch statement takes a string literal as an argument.
• Output 2
• Enter array index: 2
• Enter numerator: 5
• Enter denominator: 0
• Error: Cannot divide by 0
• Here, the denominator is 0. So we throw the int literal 0. This exception is
caught by the second catch block.
• If any other exception occurs, it is caught by the default catch block.
• Output 3
• Enter array index: 2
• Enter numerator: 5
• Enter denominator: 2
• 2.5
• Here, the program runs without any problem as no exception occurs.
C++ Files
• The fstream library allows us to work with files.
• To use the fstream library, include both the standard <iostream> AND the <fstream> header file:
• Example
• #include <iostream>
• #include <fstream>
• There are three classes included in the fstream library, which are used to create, write or read
files:
• Class Description
• ofstream Creates and writes to files
• ifstream Reads from files
• fstream A combination of ofstream and ifstream: creates, reads, and writes to files
Create and Write To a File
• To create a file, use either Example
the ofstream or fstream #include <iostream>
class, and specify the name #include <fstream>
of the file. using namespace std;
• MyWriteFile.close();
Exercise