Неправильно считывается число из бинарного файла
class PizzeriaDB {
public:
~PizzeriaDB() = default;
std::vector<Pizza> getPizzasAvailable() const;
void addClient(std::string, std::string);
void addEmployee(const std::string& name);
void deleteEmployee(const std::string& s);
void addPizza(const std::string& name, double price);
void deletePizza(const std::string& s);
void setAdminKey(const std::string& s);
bool AdminIsValid(const std::string&) const;
bool ClientIsValid(const std::string&, const std::string&) const;
void newOrder(const Order& o);
void complete_order();
void GetDB();
void SaveDB();
private:
std::string AdminKey = "superadmin";
std::vector<Pizza> availablePizzas;
std::vector<Employee> workers;
std::map<std::string, std::string> clientData;
std::queue<Order> current_orders;
};
class Employee {
public:
Employee() = default;
Employee(const std::string& name, bool free = true);
void doWork(const Order& o);
bool isFree() const;
std::string getName() const;
void SetName(const std::string& n) {
name = n;
}
void SetFree(bool f) {
free = f;
}
// Методы для получения данных
const std::string& GetName() const {
return name;
}
bool IsFree() const {
return free;
}
private:
std::string name;
bool free = 1;
};
class Pizza {
public:
Pizza() = default;
~Pizza() {};
Pizza(const std::string& type, double price, int amount = 1);
std::string getType() const;
double getPrice() const;
int getAmount() const;
std::string getName() const;
void SetPizzaType(const std::string& type) {
pizza_type = type;
}
void SetPrice(double p) {
price = p;
}
void SetAmount(unsigned int a) {
amount = a;
}
const std::string& GetPizzaType() const {
return pizza_type;
}
double GetPrice() const {
return price;
}
unsigned int GetAmount() const {
return amount;
}
private:
std::string pizza_type;
double price = 1;
unsigned int amount = 1;
};
void PizzeriaDB::SaveDB() {
// Запись PizzaCatalogue
out.open("PizzaCatalogue.bin", std::ios::binary | std::ios::out);
if (!out) {
std::cout << "Failed to open PizzaCatalogue.bin for writing." << std::endl;
return;
}
size_t pizzaCount = availablePizzas.size();
out.write((char*)&pizzaCount, sizeof(size_t));
for (const auto& pizza : availablePizzas) {
size_t typeLen = pizza.GetPizzaType().size();
out.write((char*)&typeLen, sizeof(size_t));
const std::string& pizzaType = pizza.GetPizzaType();
out.write(pizzaType.c_str(), typeLen);
double price = pizza.GetPrice();
out.write((char*)&price, sizeof(double));
}
out.close();
// Запись WorkersDB
out.open("WorkersDB.bin", std::ios::binary | std::ios::out);
if (!out) {
std::cout << "Failed to open WorkersDB.bin for writing." << std::endl;
return;
}
size_t workerCount = workers.size();
out.write((char*)&workerCount, sizeof(size_t));
for (const auto& worker : workers) {
size_t nameLen = worker.GetName().size();
out.write((char*)&nameLen, sizeof(size_t));
out.write(worker.GetName().c_str(), nameLen);
}
out.close();
}
void PizzeriaDB::GetDB() {
// Чтение PizzaCatalogue
in.open("PizzaCatalogue.bin", std::ios::binary);
if (!in) {
std::cout << "Failed to open PizzaCatalogue.bin for reading." << std::endl;
return;
}
if (in.peek() == std::ifstream::traits_type::eof()) {
// Файл пуст, пропускаем чтение
return;
}
size_t pizzaCount;
in.read((char*)&pizzaCount, sizeof(size_t));
availablePizzas.resize(pizzaCount);
for (size_t i = 0; i < pizzaCount; ++i) {
Pizza pizza;
size_t typeLen;
in.read((char*)&typeLen, sizeof(size_t));
std::string pizzaType(typeLen, '\0');
in.read(&pizzaType[0], typeLen);
pizza.SetPizzaType(pizzaType);
double price;
in.read((char*)&price, sizeof(double));
pizza.SetPrice(price);
availablePizzas[i] = pizza;
}
in.close();
// Чтение WorkersDB
in.open("WorkersDB.bin", std::ios::binary);
if (!in) {
std::cout << "Failed to open WorkersDB.bin for reading." << std::endl;
return;
}
if (in.peek() == std::ifstream::traits_type::eof()) {
// Файл пуст, пропускаем чтение
return;
}
size_t workerCount;
in.read((char*)&workerCount, sizeof(size_t));
workers.resize(workerCount);
for (size_t i = 0; i < workerCount; ++i) {
Employee employee;
size_t nameLen = 20;
in.read((char*)&nameLen, sizeof(size_t));
std::string name(nameLen, '\0');
in.read(&name[0], nameLen);
employee.SetName(name);
bool isFree;
in.read((char*)&isFree, sizeof(bool));
employee.SetFree(isFree);
workers[i] = employee;
}
in.close();
}
У пицц все записывается и считывается хорошо. А вот у работников, именно у второго работника не считывается размер имени. Заносится рандомное большое число(лимит size_t наверное) и потом string не конструируется из за нехватки памяти. По сути алгоритмы записи и чтения одинаковые, что у пицц, что у работников.
Ответы (1 шт):
Автор решения: Harry
→ Ссылка
Итак, мы пишем для работника...
for (const auto& worker : workers) {
size_t nameLen = worker.GetName().size();
out.write((char*)&nameLen, sizeof(size_t));
out.write(worker.GetName().c_str(), nameLen);
}
Длину строки, строку. Всё.
А что мы читаем?
in.read((char*)&nameLen, sizeof(size_t));
std::string name(nameLen, '\0');
in.read(&name[0], nameLen);
employee.SetName(name);
bool isFree;
in.read((char*)&isFree, sizeof(bool));
Длину строки, строку, булеву переменную.
Дальше пояснять не надо? Если, грубо говоря, из кошелька брать то, что ты туда не клал — неприятности не заставят себя ждать :)