Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <boost/lexical_cast.hpp>
- #include <iomanip>
- #include <experimental/filesystem>
- #include <functional>
- #include <iostream>
- #include <fstream>
- #include <string>
- std::string ftos(float);
- bool check_file(std::fstream& file)
- {
- if (file.fail() || file.eof())
- {
- return false;
- }
- auto pos = file.tellg();
- file.seekg(0, std::ios::end);
- auto pos1 = file.tellg();
- if (pos == pos1) // for binary file
- {
- return false;
- }
- pos1 -= 1; // -1 too
- if (pos == pos1) // for text file ('\n' is before the eof)
- {
- return false;
- }
- pos1 -= 1;
- if (pos == pos1)
- {
- return false;
- }
- file.seekg(pos);
- return true;
- }
- class Detail
- {
- public:
- Detail(int i = 0, float m = 0, const std::string& n = "")
- : id(i), mass(m), name(n)
- { }
- Detail(const Detail& rhs)
- : id(rhs.id), mass(rhs.mass), name(rhs.name)
- { }
- ~Detail() { }
- friend std::istream& operator>>(std::istream& is, Detail& detail)
- {
- is >> detail.id >> detail.mass >> detail.name;
- return is;
- }
- friend std::ostream& operator<<(std::ostream& os, const Detail& detail)
- {
- os << detail.id << " " << detail.mass << " " << detail.name << "\n";
- return os;
- }
- Detail& operator=(const Detail& rhs)
- {
- if (this != &rhs)
- {
- id = rhs.id;
- mass = rhs.mass;
- name = rhs.name;
- }
- return *this;
- }
- std::fstream& write(std::fstream& file)
- {
- if (!file.is_open())
- {
- throw std::invalid_argument("Attempt to read from closed file");
- }
- file.write(reinterpret_cast<char*>(&id), sizeof(int));
- file.write(reinterpret_cast<char*>(&mass), sizeof(float));
- auto str_size = name.size();
- file.write(reinterpret_cast<char*>(&str_size), sizeof(str_size));
- file.write(&name[0], str_size);
- return file;
- }
- std::fstream& read(std::fstream& file)
- {
- if (!file.is_open())
- {
- throw std::invalid_argument("Attempt to write to closed file");
- }
- if (!check_file(file)) // if eof was reached
- {
- file.setstate(file.rdstate() | file.failbit);
- return file;
- }
- file.read(reinterpret_cast<char*>(&id), sizeof(int));
- file.read(reinterpret_cast<char*>(&mass), sizeof(float));
- std::string::size_type str_size;
- file.read(reinterpret_cast<char*>(&str_size), sizeof(str_size));
- name.resize(str_size);
- file.read(&name[0], str_size);
- return file;
- }
- std::fstream& cwrite(std::fstream& file)
- {
- if (!file.is_open())
- {
- throw std::invalid_argument("Attempt to write to a closed file");
- }
- write_string(file, std::to_string(id));
- write_string(file, ftos(mass));
- write_string(file, name, '\n');
- return file;
- }
- std::fstream& cread(std::fstream& file)
- {
- if (!file.is_open())
- {
- throw std::invalid_argument("Attempt to read from closed file");
- }
- if (!check_file(file))
- {
- file.setstate(file.rdstate() | file.failbit);
- return file;
- }
- id = std::stoi(read_string(file));
- mass = std::stof(read_string(file));
- name = read_string(file);
- return file;
- }
- const float get_mass() const { return mass; }
- const std::string get_name() const { return name; }
- const int get_id() const { return id; }
- void set_id(int i) { id = i; }
- void set_mass(float m) { mass = m; }
- void set_name(const std::string& n) { name = n; }
- private:
- std::string read_string(std::fstream& file)
- {
- std::string str;
- char ch;
- while (1)
- {
- ch = file.get();
- if (ch == ' ' || ch == '\t' || ch == '\n' || file.eof())
- {
- break;
- }
- str += ch;
- }
- return str;
- }
- std::fstream& write_string(std::fstream& file, const std::string& str, char delim = ' ')
- {
- for (auto i : str)
- {
- file.put(i);
- }
- file.put(delim);
- return file;
- }
- int id;
- float mass;
- std::string name;
- };
- std::istream& operator>>(std::istream&, Detail&);
- std::ostream& operator<<(std::ostream&, const Detail&);
- bool operator==(const Detail& lhs, const Detail& rhs)
- {
- return lhs.get_id() == rhs.get_id() && lhs.get_mass() == rhs.get_mass() && lhs.get_name() == rhs.get_name();
- }
- bool operator!=(const Detail& lhs, const Detail& rhs)
- {
- return !(lhs == rhs);
- }
- void reverse_output(std::fstream& file, int mode)
- {
- if (!file.is_open())
- {
- throw std::invalid_argument("Attempt to read from empty file");
- }
- file.seekg(-3, std::ios::end);
- std::ios::streampos pos = file.tellg();
- Detail det;
- while (pos > 0)
- {
- for (char ch = file.get();
- pos > 0 && ch != '\n';
- ch = file.get())
- {
- if (ch != '\n')
- {
- pos -= 1;
- file.seekg(pos);
- }
- }
- if (!pos) file.seekg(pos);
- mode ? file >> det : det.cread(file);
- std::cout << det;
- if (pos)
- {
- pos -= 2;
- file.seekg(pos);
- }
- }
- }
- std::vector<Detail> find_by_id(std::fstream& file, int id, int mode)
- {
- if (!file.is_open())
- {
- throw std::invalid_argument("Trying to search in the closed file");
- }
- file.seekg(0, std::ios::beg);
- std::vector<Detail> details;
- Detail det;
- while (check_file(file))
- {
- switch (mode)
- {
- case 0:
- file >> det;
- break;
- case 1:
- det.cread(file);
- break;
- case 2:
- det.read(file);
- break;
- default:
- break;
- }
- if (det.get_id() == id)
- {
- details.emplace_back(det);
- }
- }
- return details;
- }
- void search(std::fstream& file, int id, int mode)
- {
- std::vector<Detail> details = find_by_id(file, id, mode);
- if (!details.empty())
- {
- for (auto i : details)
- {
- std::cout << i << "\n";
- }
- }
- else
- {
- std::cout << "Детали с данным id = " << id << " не найдены!" << std::endl;
- }
- }
- std::string ftos(float x)
- {
- std::string str = boost::lexical_cast<std::string>(x);
- for (auto i : str)
- {
- if (i == ',')
- {
- i = '.';
- break;
- }
- }
- return str;
- }
- void shift(std::fstream& file, std::ios::streampos p, const std::string& filename, int mode)
- {
- Detail det;
- file.seekg(p);
- while (!file.eof())
- {
- p = file.tellg();
- if (!check_file(file) || file.eof())
- {
- break;
- }
- mode ? file >> det : det.read(file);
- if (!check_file(file) || file.eof())
- {
- if (file.eof() || file.fail())
- {
- file.clear();
- }
- std::experimental::filesystem::resize_file(filename, p);
- file.seekg(std::ios::beg);
- break;
- }
- mode ? file >> det : det.read(file);
- if (p)
- {
- p += 1;
- }
- file.seekg(p);
- mode ? file << det : det.write(file);
- }
- }
- void remove(const Detail& det, std::fstream& file, const std::string& filename, int mode, std::ios::openmode openmode)
- {
- std::vector<Detail> details;
- int count = 0;
- Detail d;
- file.seekg(std::ios::beg);
- while (1)
- {
- mode ? file >> d : d.read(file);
- count++;
- if (d != det)
- {
- details.emplace_back(d);
- }
- if (!check_file(file))
- {
- break;
- }
- }
- file.clear();
- file.close();
- file.open(filename.c_str(), openmode | std::ios::trunc);
- file.seekg(std::ios::beg);
- for (auto i : details)
- {
- mode ? file << i : i.write(file);
- }
- std::cout << "Удално " << count - details.size() << " объетов" << std::endl;
- }
- float get_float(std::istream& is)
- {
- float f;
- while (!(is >> f))
- {
- std::cout << "Ошибка ввода! Введите число с плавающей точкой!" << std::endl;
- std::cin.clear();
- std::cin.ignore(static_cast<std::streamsize>(std::numeric_limits<int>::max()), '\n');
- }
- return f;
- }
- int get_int()
- {
- int i;
- while (!(std::cin >> i))
- {
- std::cout << "Ошибка ввода! Введите целое число!" << std::endl;
- std::cin.clear();
- std::cin.ignore(static_cast<std::streamsize>(std::numeric_limits<int>::max()), '\n');
- }
- return i;
- }
- Detail get_detail(std::istream& is)
- {
- Detail det;
- det.set_id(get_int());
- float mass;
- do
- {
- mass = get_float(is);
- if (mass <= 0)
- {
- std::cout << "Введите положительное значение\n";
- }
- } while (mass <= 0);
- det.set_mass(mass);
- std::string name;
- is >> name;
- det.set_name(name);
- return det;
- }
- void menu()
- {
- std::cout << "Выберите действие:" << std::endl << std::endl;
- std::cout << std::setw(50) << std::left << "1)Создать деталь " << "8)Вывод содержимого текстового файла в обратном порядке\n";
- std::cout << std::setw(50) << std::left << "2)Запись детали в текстовый файn " << "9)Посивольный вывод текстового файла в обратном порядке\n";
- std::cout << std::setw(50) << std::left << "3)Запись детали в бинарный файл " << "10)Поиск записей по id в тектсовом файле\n";
- std::cout << std::setw(50) << std::left << "4)Запись детали в текстовый файл посимвольно " << "11)Поиск записей по id в тектсовом файле(посимвольное считывание)\n";
- std::cout << std::setw(50) << std::left << "5)Вывод содержимого текстового файла " << "12)Поиск записей по id в бинарном файле\n";
- std::cout << std::setw(50) << std::left << "6)Посимвольный вывод содержимого текстового файла " << "13)Удаление записиси из текстового файла\n";
- std::cout << std::setw(50) << std::left << "7)Вывод содержимого бинарного файла " << "14)Удаление записиси из бинарного файла\n";
- std::cout << std::setw(50) << std::left << "0)Закончить " << "15)Очистить экран\n";
- }
- int choose()
- {
- int i;
- while (1)
- {
- i = get_int();
- if (i > 15 || i < 0)
- {
- std::cout << "Некорректный ввод!" << std::endl;;
- }
- else
- {
- break;
- }
- }
- return i;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement