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