#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__