Week 12: File Handling, Exceptions, and Your Path Forward
Learn to interact with files, handle errors gracefully, and plan your continued C++ journey.
Explore Chapter 12Chapter 12: Working with Files and Looking Ahead
File I/O (`fstream`).
Many applications need to read data from files or write results to files. C++ provides the `fstream` library for file input/output operations.
You typically need to include the `
#include <fstream> // For file stream operations
#include <iostream> // For std::cout, std::cerr
#include <string> // For std::string
Writing to Files (`ofstream`)
Use `std::ofstream` (output file stream) to write data to a file. If the file doesn't exist, it's created. If it does exist, its contents are typically discarded by default (use `std::ios::app` mode to append).
// Create and open a file for writing
std::ofstream outputFile("output.txt");
if (outputFile.is_open()) { // Always check if the file opened successfully
outputFile << "This is the first line.\n";
outputFile << "Writing some data: " << 123 << "\n";
outputFile.close(); // Close the file when done
std::cout << "Successfully wrote to output.txt\n";
} else {
std::cerr << "Unable to open file for writing!\n";
}
Reading from Files (`ifstream`)
Use `std::ifstream` (input file stream) to read data from a file.
std::string line;
std::ifstream inputFile("output.txt"); // Open the file we just wrote
if (inputFile.is_open()) {
std::cout << "Reading from output.txt:\n";
// Read line by line
while (std::getline(inputFile, line)) {
std::cout << line << '\n';
}
inputFile.close(); // Close the file
} else {
std::cerr << "Unable to open file for reading!\n";
}
Remember to check if files opened correctly using `is_open()` and to `close()` files when you're finished. Using file streams within objects whose destructors automatically close the file (RAII principle) is a more robust approach, especially when dealing with potential errors.
Basic Error Handling (`try`, `catch`, `throw`).
Errors and exceptional situations can occur during program execution (e.g., trying to open a non-existent file, dividing by zero, invalid user input). C++ provides exception handling mechanisms to deal with these situations gracefully.
Core Components
- `try` Block: Encloses the code that might potentially throw an exception.
- `catch` Block: Follows a `try` block. Contains the code to handle a specific type of exception if one is thrown within the `try` block. You can have multiple `catch` blocks for different exception types.
- `throw` Statement: Used to signal that an exceptional situation has occurred. You typically throw an object (often an instance of a class derived from `std::exception`).
Example
#include <iostream>
#include <stdexcept> // For standard exception classes like std::runtime_error
double divide(double numerator, double denominator) {
if (denominator == 0.0) {
throw std::runtime_error("Math error: Attempted to divide by zero"); // Throw an exception
}
return numerator / denominator;
}
int main() {
double a = 10.0;
double b = 0.0;
double result;
try {
std::cout << "Attempting division..." << std::endl;
result = divide(a, b); // This might throw
std::cout << "Result: " << result << std::endl; // Won't execute if exception occurs
}
catch (const std::runtime_error& e) { // Catch the specific exception type
std::cerr << "Exception caught: " << e.what() << '\n'; // .what() gets the error message
}
// Can have more catch blocks for different exception types
// catch (...) { // Catches any type of exception (use sparingly)
// std::cerr << "An unknown error occurred.\n";
// }
std::cout << "Program continues after try-catch block." << std::endl;
return 0;
}
Exception handling allows your program to recover from errors or terminate in a more controlled manner instead of crashing abruptly.
Mini-Project Idea.
To consolidate your learning, try creating a small project. This helps reinforce concepts and exposes practical challenges.
Idea: Simple Contact Management System
- Define a `Contact` class: With private members for name, phone number, email. Include a constructor and public getter methods.
- Use `std::vector` or `std::map`: Store multiple `Contact` objects in an STL container (e.g., `std::vector
`). - Implement Core Features (Functions):
- `addContact()`: Prompts the user for details and adds a new `Contact` object to your container.
- `viewContacts()`: Iterates through the container and displays all contact details neatly.
- `searchContact()`: Prompts for a name and displays the details if found.
- (Optional) `saveToFile()`: Writes the contact list to a text file using `ofstream`.
- (Optional) `loadFromFile()`: Reads the contact list from the text file using `ifstream` when the program starts.
- Create a Menu (`main` function): Use a loop (`do...while` is good here) to present a menu to the user (Add, View, Search, Exit) and call the appropriate functions based on their input.
- (Optional) Add Basic Error Handling: Use `try-catch` for file operations or potentially invalid input.
This project integrates classes, STL containers, file I/O, functions, and control flow.
Where to Go Next?
Congratulations on completing this 12-week introduction to C++!
You now have a strong foundation. The world of C++ is vast and deep. Here are some areas to explore further:
- Advanced STL: Explore more containers (`queue`, `stack`, `priority_queue`), advanced algorithms, and allocators.
- Templates In-Depth: Master function templates and class templates for writing truly generic code.
- Advanced OOP: Multiple inheritance, virtual inheritance, operator overloading, design patterns.
- Modern C++ Features: Dive deeper into C++11, C++14, C++17, C++20 features (smart pointers, lambdas, concurrency features, modules, concepts, ranges, etc.).
- Build Systems: Learn tools like CMake or Make for managing larger projects.
- Debugging Tools: Get proficient with debuggers like GDB or the debugger integrated into your IDE.
- Specific Application Domains:
- Game Development: Unreal Engine (C++), custom engines, graphics libraries (OpenGL, Vulkan, DirectX).
- System Programming: OS interaction, networking, low-level optimization.
- High-Performance Computing: Parallel programming (OpenMP, MPI), libraries like Boost.
- Embedded Systems: Programming microcontrollers and resource-constrained devices.
- Contribute to Open Source: Find a C++ project you're interested in and contribute!
The best way to learn is by building projects that interest you. Keep coding, keep experimenting, and keep learning!