Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

Error Handling in I/O - C++ Language

Introduction

Error handling is a critical aspect of programming, especially when dealing with input and output (I/O) operations. In C++, I/O operations can fail due to various reasons such as file not found, permission denied, or hardware failure. Handling these errors gracefully ensures that the program can respond appropriately and avoid unexpected crashes.

Basic Error Handling

C++ provides several mechanisms for error handling in I/O operations. The simplest form involves checking the state of the I/O streams using member functions. Here are some commonly used functions:

  • bad(): Returns true if a non-recoverable error has occurred.
  • fail(): Returns true if an input/output operation has failed.
  • eof(): Returns true if the end of the file has been reached.
  • good(): Returns true if none of the above errors has occurred.

Here's an example:

#include <iostream>
#include <fstream>

int main() {
    std::ifstream infile("example.txt");

    if (!infile) {
        std::cerr << "Error opening file!" << std::endl;
        return 1;
    }

    char c;
    while (infile.get(c)) {
        std::cout << c;
    }

    if (infile.eof()) {
        std::cout << "End of file reached." << std::endl;
    } else if (infile.fail()) {
        std::cerr << "Input failure!" << std::endl;
    }

    infile.close();
    return 0;
}
                

Using Exceptions for Error Handling

Another way to handle errors in C++ is by using exceptions. Exceptions provide a way to react to exceptional circumstances (like runtime errors) in programs by transferring control to special functions called handlers. Here's how to use exceptions for error handling in I/O:

#include <iostream>
#include <fstream>
#include <stdexcept>

void readFile(const std::string& filename) {
    std::ifstream infile(filename);
    if (!infile) {
        throw std::runtime_error("Error opening file!");
    }

    char c;
    while (infile.get(c)) {
        std::cout << c;
    }

    if (infile.fail() && !infile.eof()) {
        throw std::runtime_error("Input failure!");
    }

    infile.close();
}

int main() {
    try {
        readFile("example.txt");
    } catch (const std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }

    return 0;
}
                

Advanced Error Handling

In more complex applications, you may need to handle multiple types of errors differently. You can define custom exception classes to provide more context-specific error information:

#include <iostream>
#include <fstream>
#include <stdexcept>

class FileOpenException : public std::runtime_error {
public:
    FileOpenException(const std::string& message)
        : std::runtime_error(message) {}
};

class FileReadException : public std::runtime_error {
public:
    FileReadException(const std::string& message)
        : std::runtime_error(message) {}
};

void readFile(const std::string& filename) {
    std::ifstream infile(filename);
    if (!infile) {
        throw FileOpenException("Error opening file: " + filename);
    }

    char c;
    while (infile.get(c)) {
        if (infile.fail()) {
            throw FileReadException("Error reading file: " + filename);
        }
        std::cout << c;
    }

    infile.close();
}

int main() {
    try {
        readFile("example.txt");
    } catch (const FileOpenException& e) {
        std::cerr << "FileOpenException: " << e.what() << std::endl;
    } catch (const FileReadException& e) {
        std::cerr << "FileReadException: " << e.what() << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }

    return 0;
}
                

Conclusion

Error handling in I/O operations is an essential part of robust C++ programming. By using stream state functions and exceptions, you can effectively manage errors and ensure your program behaves correctly under various conditions. Always strive to handle errors gracefully to improve the user experience and maintain the integrity of your applications.