C/C++ Arena

Step 5 of 6

RAII wrappers for C libraries

Enterprise C++ constantly calls C libraries (OS APIs, databases, compression, crypto) that hand out handles you must release: FILE* with fclose, sqlite3* with sqlite3_close, and so on. Wrap each one immediately in a std::unique_ptr with a custom deleter, so it's released on every path, exactly once:

struct FileCloser {
    void operator()(FILE* f) const { if (f) std::fclose(f); }
};
using File = std::unique_ptr<FILE, FileCloser>;

File f(std::fopen("data.txt", "r"));     // closes itself
if (!f) { /* open failed */ }
std::fgets(buf, sizeof buf, f.get());    // .get() for the raw handle

Your turn: write the FileCloser, the File alias, File open_file(path, mode), and std::optional<std::string> first_line(path), which returns the file's first line (without the newline) or std::nullopt if it can't be opened or is empty. No manual fclose in first_line.

Previous: Pimpl Next: Challenge: a table-driven state machine