cpp

exercises

exercises.cpp⚙️
/**
 * Exception Handling - Exercises
 * Compile: g++ -std=c++17 -Wall exercises.cpp -o exercises
 */

#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
using namespace std;

// ============================================================
// Exercise 1: Safe Division ⭐
// ============================================================

// TODO: Create safeDivide(a, b) that throws invalid_argument
// if b is zero. Test with try-catch.

void exercise1() {
    // try {
    //     cout << safeDivide(10, 2) << endl;  // 5
    //     cout << safeDivide(10, 0) << endl;  // throws
    // } catch (const invalid_argument& e) { ... }
    cout << "(Implement safeDivide)" << endl;
}

// ============================================================
// Exercise 2: Range Validator ⭐⭐
// ============================================================

// TODO: Create validateRange(value, min, max) that throws
// out_of_range if value is not in [min, max]

void exercise2() {
    // validateRange(50, 1, 100);  // OK
    // validateRange(150, 1, 100); // throws
    cout << "(Implement validateRange)" << endl;
}

// ============================================================
// Exercise 3: Custom Exception Class ⭐⭐
// ============================================================

// TODO: Create NegativeValueException that stores the
// negative value that caused the error

void exercise3() {
    // throw NegativeValueException(-5);
    // catch: e.what() returns message
    //        e.getValue() returns -5
    cout << "(Implement NegativeValueException)" << endl;
}

// ============================================================
// Exercise 4: Exception Chain ⭐⭐
// ============================================================

// TODO: Create 3 functions that call each other
// Inner throws, middle logs and rethrows, outer catches

void exercise4() {
    // outer() catches from middle() which catches from inner()
    cout << "(Implement exception chain)" << endl;
}

// ============================================================
// Exercise 5: Multiple Exception Types ⭐⭐⭐
// ============================================================

// TODO: Create function that can throw different exceptions
// based on error code. Handle each type differently.

void exercise5() {
    // processError(1) -> throws invalid_argument
    // processError(2) -> throws out_of_range
    // processError(3) -> throws runtime_error
    cout << "(Implement multiple exception types)" << endl;
}

// ============================================================
// Exercise 6: Exception-Safe Stack ⭐⭐⭐
// ============================================================

// TODO: Create Stack class that throws on pop() when empty
// and on push() when full (fixed size)

void exercise6() {
    // Stack<int, 3> s;
    // s.pop();  // throws "Stack empty"
    // s.push(1); s.push(2); s.push(3);
    // s.push(4);  // throws "Stack full"
    cout << "(Implement exception-safe Stack)" << endl;
}

// ============================================================
// Exercise 7: Resource Manager ⭐⭐⭐
// ============================================================

// TODO: Create RAII wrapper that demonstrates proper
// cleanup even when exceptions occur

void exercise7() {
    // ResourceGuard acquires resource in ctor
    // releases in dtor, even on exception
    cout << "(Implement ResourceGuard RAII)" << endl;
}

// ============================================================
// Exercise 8: Validation System ⭐⭐⭐
// ============================================================

// TODO: Create validation system with multiple exception types
// - EmptyFieldException
// - InvalidFormatException  
// - OutOfRangeException
// Each with relevant error information

void exercise8() {
    // validate("", "email");        // EmptyFieldException
    // validate("invalid", "email"); // InvalidFormatException
    // validate("-5", "age");        // OutOfRangeException
    cout << "(Implement validation exception system)" << endl;
}

// ============================================================
// MAIN
// ============================================================

int main() {
    cout << "=== Exception Handling Exercises ===" << endl;
    
    cout << "\nEx1: Safe Division" << endl;
    exercise1();
    
    cout << "\nEx2: Range Validator" << endl;
    exercise2();
    
    cout << "\nEx3: Custom Exception" << endl;
    exercise3();
    
    cout << "\nEx4: Exception Chain" << endl;
    exercise4();
    
    cout << "\nEx5: Multiple Types" << endl;
    exercise5();
    
    cout << "\nEx6: Exception-Safe Stack" << endl;
    exercise6();
    
    cout << "\nEx7: Resource Manager" << endl;
    exercise7();
    
    cout << "\nEx8: Validation System" << endl;
    exercise8();
    
    return 0;
}

// ============================================================
// ANSWERS
// ============================================================
/*
Ex1:
double safeDivide(double a, double b) {
    if (b == 0) throw invalid_argument("Division by zero");
    return a / b;
}

Ex2:
void validateRange(int value, int min, int max) {
    if (value < min || value > max) {
        throw out_of_range("Value " + to_string(value) + 
            " not in range [" + to_string(min) + "," + to_string(max) + "]");
    }
}

Ex3:
class NegativeValueException : public exception {
    int value;
    string msg;
public:
    NegativeValueException(int v) : value(v), 
        msg("Negative value: " + to_string(v)) {}
    const char* what() const noexcept override { return msg.c_str(); }
    int getValue() const { return value; }
};

Ex6:
template<typename T, size_t N>
class Stack {
    T data[N];
    size_t top = 0;
public:
    void push(const T& val) {
        if (top >= N) throw overflow_error("Stack full");
        data[top++] = val;
    }
    T pop() {
        if (top == 0) throw underflow_error("Stack empty");
        return data[--top];
    }
};

Ex7:
class ResourceGuard {
public:
    ResourceGuard() { cout << "Resource acquired" << endl; }
    ~ResourceGuard() { cout << "Resource released" << endl; }
};
void test() {
    ResourceGuard rg;
    throw runtime_error("Error");
    // rg.~ResourceGuard() still called!
}
*/
Exercises - C++ Tutorial | DeepML