Read/Write binary files (C++)

#include <cassert>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <vector>

struct Book
{
    Book() : m_title(""), m_author(""), m_pages(0) { }

    Book(const std::string& title, const std::string& author, uint16_t pages)
    : m_title(title), m_author(author), m_pages(pages) { }

    friend bool operator==(const Book& b1, const Book& b2)
    {
        return b1.m_title == b2.m_title &&
               b1.m_author == b2.m_author &&
               b1.m_pages == b2.m_pages;
    }

    void print()
    {
        std::cout << "Title: " << m_title << ", "
                  << "Author: " << m_author << ", "
                  << "Pages: " << m_pages << std::endl;
    }

    std::string m_title;
    std::string m_author;
    uint16_t m_pages;
};

class Library
{
public:
    Library() : m_fileName("data.bin") { }

    void add(const Book& book)
    {
        m_books.push_back(book);
    }

    size_t size()
    {
        return m_books.size();
    }

    Book& at(size_t pos)
    {
        return m_books.at(pos);
    }

    void print()
    {
        for (auto& book : m_books)
        {
            book.print();
        }
    }

    void writeToFile()
    {
        std::fstream fs(m_fileName, std::ios::out | std::ios::binary);
        if (!fs.is_open())
        {
            std::cout << "Error opening file for writing" << std::endl;
            return;
        }

        for (const auto& book : m_books)
        {
            // Write title
            uint16_t titleLen = book.m_title.size();
            fs.write(reinterpret_cast<const char*>(&titleLen),
                     sizeof(titleLen));
            fs.write(book.m_title.c_str(), titleLen); // w/o '\0'

            // Write author
            uint16_t authorLen = book.m_author.size();
            fs.write(reinterpret_cast<const char*>(&authorLen),
                     sizeof(authorLen));
            fs.write(book.m_author.c_str(), authorLen); // w/o '\0'

            // Write pages
            fs.write(reinterpret_cast<const char*>(&book.m_pages),
                     sizeof(book.m_pages));
        }

        fs.close();
    }

    void readFromFile()
    {
        std::fstream fs(m_fileName, std::ios::in | std::ios::binary);
        if (!fs.is_open())
        {
            std::cout << "Error opening file for reading" << std::endl;
            return;
        }

        while (!fs.eof())
        {
            Book book;

            // Read title
            uint16_t titleLen;
            fs.read(reinterpret_cast<char*>(&titleLen),
                    sizeof(titleLen));
            book.m_title.resize(titleLen);
            fs.read(&book.m_title[0], titleLen);

            // Read author
            uint16_t authorLen;
            fs.read(reinterpret_cast<char*>(&authorLen),
                    sizeof(authorLen));
            book.m_author.resize(authorLen);
            fs.read(&book.m_author[0], authorLen);

            // Read pages
            fs.read(reinterpret_cast<char*>(&book.m_pages),
                    sizeof(book.m_pages));

            m_books.push_back(book);

            fs.peek();
        }

        fs.close();
    }

private:
    std::vector<Book> m_books;
    const char* m_fileName;
};

int main()
{
    Library lib1;
    lib1.add(Book("The Hound of the Baskervilles", "A.C. Doyle", 224));
    lib1.add(Book("The Fellowship of the Ring", "J.R.R. Tolkien", 576));
    lib1.writeToFile();

    Library lib2;
    lib2.readFromFile();

    assert(lib1.size() == lib2.size());

    for(size_t i = 0; i < lib1.size(); ++i)
    {
        assert(lib1.at(i) == lib2.at(i));
    }
    
    std::cout << "All tests successful" << std::endl;

    return 0;
}

00   1d00 5468 6520 486f 756e 6420 6f66 2074   __The Hound of t
10   6865 2042 6173 6b65 7276 696c 6c65 730a   he Baskervilles_
20   0041 2e43 2e20 446f 796c 65e0 001a 0054   _A.C. Doyle____T
30   6865 2046 656c 6c6f 7773 6869 7020 6f66   he Fellowship of
40   2074 6865 2052 696e 670e 004a 2e52 2e52    the Ring__J.R.R
50   2e20 546f 6c6b 6965 6e40 02               . Tolkien__