Files and Event Handling
Work with file I/O, multi-file programs, exception handling, and event-driven programming.
7.1 Streams and Files
Reading from and writing to files using C++ streams.
| Aspect | Definition | Example |
|---|---|---|
| Input Stream (ifstream) | Reads data from files. |
ifstream inFile("data.txt");
|
| Output Stream (ofstream) | Writes data to files. |
ofstream outFile("data.txt");
|
| Input-Output Stream (fstream) | Reads and writes data to files. |
fstream file("data.txt", ios::in | ios::out);
|
| File Modes | Determine file access type. |
ios::in, ios::out, ios::app
|
| Error Handling | Checks file state. |
if (!inFile.is_open()) { /* Handle Error */ }
|
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// Writing to a file
ofstream outFile("tesla_data.txt");
if (outFile.is_open()) {
outFile << "Tesla Model Information" << endl;
outFile << "========================" << endl;
outFile << "Model 3: Affordable sedan" << endl;
outFile << "Model S: Luxury sedan" << endl;
outFile << "Model X: SUV with falcon doors" << endl;
outFile << "Model Y: Compact SUV" << endl;
outFile.close();
cout << "Data written to file successfully!" << endl;
} else {
cout << "Error opening file for writing!" << endl;
}
return 0;
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
// Reading from a file
ifstream inFile("tesla_data.txt");
if (inFile.is_open()) {
string line;
cout << "Reading from file:" << endl;
cout << "==================" << endl;
while (getline(inFile, line)) {
cout << line << endl;
}
inFile.close();
} else {
cout << "Error opening file for reading!" << endl;
}
return 0;
}
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// Appending to a file
ofstream outFile("tesla_data.txt", ios::app);
if (outFile.is_open()) {
outFile << endl << "Additional Information:" << endl;
outFile << "Cybertruck: Electric pickup truck" << endl;
outFile << "Roadster: High-performance sports car" << endl;
outFile.close();
cout << "Data appended to file successfully!" << endl;
} else {
cout << "Error opening file for appending!" << endl;
}
// Read and display the updated file
ifstream inFile("tesla_data.txt");
if (inFile.is_open()) {
string line;
cout << endl << "Updated file contents:" << endl;
cout << "======================" << endl;
while (getline(inFile, line)) {
cout << line << endl;
}
inFile.close();
}
return 0;
}
7.2 Multi-File Programs
Organizing code across multiple files for better modularity.
| Aspect | Definition | Example |
|---|---|---|
| Header File | Declares functions/classes. |
MyHeader.h
|
| Source File | Implements functions/classes. |
MyImplementation.cpp
|
| Main File | Contains the main() function. |
MainFile.cpp
|
| Compilation Process | Links multiple files. |
g++ main.cpp impl.cpp -o program
|
| Use Case | Modular code organization. |
Separates declaration, implementation, main logic
|
๐ Multi-File Program Structure
Example of organizing a program across multiple files:
Tesla.h (Header File)
#ifndef TESLA_H
#define TESLA_H
#include <string>
using namespace std;
class Tesla {
private:
string model;
int batteryLevel;
public:
Tesla(string m, int battery);
void charge(int amount);
void drive(int distance);
void displayInfo();
int getBatteryLevel();
};
#endif
Tesla.cpp (Implementation File)
#include <iostream>
#include "Tesla.h"
using namespace std;
Tesla::Tesla(string m, int battery) {
model = m;
batteryLevel = battery;
}
void Tesla::charge(int amount) {
batteryLevel += amount;
if (batteryLevel > 100) batteryLevel = 100;
cout << "Charged! Battery: " << batteryLevel << "%" << endl;
}
void Tesla::drive(int distance) {
int consumption = distance / 5;
batteryLevel -= consumption;
if (batteryLevel < 0) batteryLevel = 0;
cout << "Drove " << distance << " km. Battery: " << batteryLevel << "%" << endl;
}
void Tesla::displayInfo() {
cout << "Model: " << model << endl;
cout << "Battery: " << batteryLevel << "%" << endl;
}
int Tesla::getBatteryLevel() {
return batteryLevel;
}
main.cpp (Main File)
#include <iostream>
#include "Tesla.h"
using namespace std;
int main() {
Tesla model3("Model 3", 80);
cout << "Initial state:" << endl;
model3.displayInfo();
cout << endl << "Driving 100 km..." << endl;
model3.drive(100);
cout << endl << "Charging 30%..." << endl;
model3.charge(30);
cout << endl << "Final state:" << endl;
model3.displayInfo();
return 0;
}
// Compile with: g++ main.cpp Tesla.cpp -o tesla_program
7.3 Exception Handling
Handling runtime errors gracefully using try-catch blocks.
| Aspect | Definition | Example |
|---|---|---|
| try Block | Code that may throw exceptions. |
try { /* Code */ }
|
| throw Statement | Signals an exception. |
throw runtime_error("Error!");
|
| catch Block | Handles the thrown exception. |
catch (exception &e) { cout << e.what(); }
|
| Multiple Catch Blocks | Handles different exception types. |
catch (int) and catch (string)
|
| Standard Exceptions | Predefined exceptions in C++. |
bad_alloc, invalid_argument, out_of_range
|
#include <iostream>
#include <stdexcept>
using namespace std;
// Function that throws exception
double divide(double a, double b) {
if (b == 0) {
throw runtime_error("Division by zero!");
}
return a / b;
}
// Function with multiple exception types
int getArrayElement(int arr[], int size, int index) {
if (index < 0 || index >= size) {
throw out_of_range("Index out of range!");
}
return arr[index];
}
int main() {
// Example 1: Basic exception handling
try {
double result = divide(10, 2);
cout << "Result: " << result << endl;
result = divide(10, 0); // This will throw
cout << "This won't execute" << endl;
}
catch (runtime_error& e) {
cout << "Error caught: " << e.what() << endl;
}
// Example 2: Multiple catch blocks
try {
int numbers[] = {10, 20, 30, 40, 50};
cout << endl << "Element at index 2: " << getArrayElement(numbers, 5, 2) << endl;
cout << "Element at index 10: " << getArrayElement(numbers, 5, 10) << endl;
}
catch (out_of_range& e) {
cout << "Out of range error: " << e.what() << endl;
}
catch (exception& e) {
cout << "General exception: " << e.what() << endl;
}
// Example 3: Throwing different types
try {
int age = -5;
if (age < 0) {
throw invalid_argument("Age cannot be negative!");
}
}
catch (invalid_argument& e) {
cout << endl << "Invalid argument: " << e.what() << endl;
}
cout << endl << "Program continues after exception handling" << endl;
return 0;
}
#include <iostream>
#include <exception>
using namespace std;
// Custom exception class
class BatteryException : public exception {
private:
string message;
public:
BatteryException(string msg) : message(msg) {}
const char* what() const noexcept override {
return message.c_str();
}
};
class Tesla {
private:
int batteryLevel;
public:
Tesla(int battery) : batteryLevel(battery) {}
void drive(int distance) {
int consumption = distance / 5;
if (batteryLevel - consumption < 0) {
throw BatteryException("Insufficient battery to drive this distance!");
}
batteryLevel -= consumption;
cout << "Drove " << distance << " km. Battery: " << batteryLevel << "%" << endl;
}
void charge(int amount) {
if (amount < 0) {
throw BatteryException("Charge amount cannot be negative!");
}
batteryLevel += amount;
if (batteryLevel > 100) batteryLevel = 100;
cout << "Charged! Battery: " << batteryLevel << "%" << endl;
}
};
int main() {
try {
Tesla model3(30);
model3.drive(50); // OK
model3.charge(40); // OK
model3.drive(200); // This will throw
}
catch (BatteryException& e) {
cout << "Battery Error: " << e.what() << endl;
}
return 0;
}
7.4 Event Handling
Responding to events and user interactions in programs.
| Aspect | Definition | Example |
|---|---|---|
| Event Source | Object that generates an event. |
Button, Mouse, Keyboard
|
| Event Listener | Responds to the event. |
onClick() for button clicks
|
| Event Propagation | Flow of events through a hierarchy. |
Capturing, Target, Bubbling phases
|
| Practical Applications | Handles user/system interactions. |
Button clicks, file changes, key presses
|
| Error Handling | Ensures robust event processing. |
Try-catch blocks for listener logic
|
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
// Event handler type
typedef function<void()> EventHandler;
// Simple event system
class Button {
private:
string label;
vector<EventHandler> clickHandlers;
public:
Button(string l) : label(l) {}
// Register event handler
void onClick(EventHandler handler) {
clickHandlers.push_back(handler);
}
// Trigger the event
void click() {
cout << "Button '" << label << "' clicked!" << endl;
for (auto& handler : clickHandlers) {
handler();
}
}
};
// Event with parameters
class TeslaEvent {
private:
string eventType;
int batteryLevel;
public:
TeslaEvent(string type, int battery)
: eventType(type), batteryLevel(battery) {}
string getType() { return eventType; }
int getBatteryLevel() { return batteryLevel; }
};
typedef function<void(TeslaEvent)> TeslaEventHandler;
class TeslaEventSystem {
private:
vector<TeslaEventHandler> handlers;
public:
void subscribe(TeslaEventHandler handler) {
handlers.push_back(handler);
}
void trigger(TeslaEvent event) {
for (auto& handler : handlers) {
handler(event);
}
}
};
int main() {
// Simple button events
Button startButton("Start");
Button stopButton("Stop");
startButton.onClick([]() {
cout << " -> Starting Tesla..." << endl;
});
startButton.onClick([]() {
cout << " -> Initializing systems..." << endl;
});
stopButton.onClick([]() {
cout << " -> Stopping Tesla..." << endl;
});
startButton.click();
cout << endl;
stopButton.click();
// Tesla event system
cout << endl << "Tesla Event System:" << endl;
cout << "===================" << endl;
TeslaEventSystem eventSystem;
eventSystem.subscribe([](TeslaEvent e) {
cout << "Event: " << e.getType() << endl;
cout << "Battery Level: " << e.getBatteryLevel() << "%" << endl;
});
eventSystem.subscribe([](TeslaEvent e) {
if (e.getBatteryLevel() < 20) {
cout << "WARNING: Low battery!" << endl;
}
});
eventSystem.trigger(TeslaEvent("Battery Update", 15));
return 0;
}
๐ก Practice Exercise
Master file handling and events with these exercises:
- Create a program to read and write student records to a file
- Organize a project into header, implementation, and main files
- Implement exception handling for file operations
- Create a custom exception class for your application
- Build a simple event system with multiple event types
Congratulations!
You've completed all 7 chapters of the C++ Interactive Learning Platform! You now have a solid foundation in C++ programming.