C++: An account with its own errors

Define your own error types and handle them differently.

What to build

Two exception classes, thrown by one function and handled by its caller.

Requirements

  • Define BadAmount and NotEnough, both derived from runtime_error.
  • deposit X and withdraw X change a balance that starts at 0.
  • An amount of 0 or less throws BadAmount, and refused: bad amount is printed.
  • Withdrawing more than the balance throws NotEnough, and refused: not enough is printed.
  • At the end, print balance B.

Input

The first line has n. Each of the next n lines is a command.

Output

One line per refusal, then the balance.

Constraints

n is from 1 to 100. Amounts are from -1000 to 100000.

Example

Input:

3
deposit 100
withdraw 150
withdraw 30

Output:

refused: not enough
balance 70

Why it works

Each exception type names one problem, so that the handlers stay simple and a new kind of error can be added without changing the others.

Examples

Example 1 · Input
3
deposit 100
withdraw 150
withdraw 30
Expected output
refused: not enough
balance 70
Example 2 · Input
2
deposit -5
withdraw 0
Expected output
refused: bad amount
refused: bad amount
balance 0

Hints

Hint 1

Derive each error from runtime_error, and pass a message to its constructor.

Hint 2

Catch the specific types before the general one.

Hint 3

Throw from the function, and catch in main.

Solution

Show one correct solution (try it yourself first)
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;

class BadAmount : public runtime_error {
public:
    BadAmount() : runtime_error("bad amount") {}
};

class NotEnough : public runtime_error {
public:
    NotEnough() : runtime_error("not enough") {}
};

void apply(const string& command, int amount, int& balance) {
    if (amount <= 0) throw BadAmount();
    if (command == "deposit") {
        balance += amount;
    } else {
        if (amount > balance) throw NotEnough();
        balance -= amount;
    }
}

int main() {
    int n, balance = 0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        string command;
        int amount;
        cin >> command >> amount;
        try {
            apply(command, amount, balance);
        } catch (const runtime_error& e) {
            cout << "refused: " << e.what() << endl;
        }
    }
    cout << "balance " << balance << endl;
    return 0;
}

Lesson: Exceptions and files →