Advertisement
3axap_010

Detail.h

Dec 12th, 2019
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.88 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <boost/lexical_cast.hpp>
  4. #include <iomanip>
  5. #include <experimental/filesystem>
  6. #include <functional>
  7. #include <iostream>
  8. #include <fstream>
  9. #include <string>
  10.  
  11. std::string ftos(float);
  12.  
  13. bool check_file(std::fstream& file)
  14. {
  15.     if (file.fail() || file.eof())
  16.     {
  17.         return false;
  18.     }
  19.  
  20.     auto pos = file.tellg();
  21.     file.seekg(0, std::ios::end);
  22.     auto pos1 = file.tellg();
  23.  
  24.     if (pos == pos1) // for binary file
  25.     {
  26.         return false;
  27.     }
  28.  
  29.     pos1 -= 1; // -1 too
  30.  
  31.     if (pos == pos1) // for text file ('\n' is before the eof)
  32.     {
  33.         return false;
  34.     }
  35.  
  36.     pos1 -= 1;
  37.     if (pos == pos1)
  38.     {
  39.         return false;
  40.     }
  41.  
  42.     file.seekg(pos);
  43.  
  44.     return true;
  45. }
  46.  
  47. class Detail
  48. {
  49. public:
  50.     Detail(int i = 0, float m = 0, const std::string& n = "")
  51.         : id(i), mass(m), name(n)
  52.     { }
  53.  
  54.     Detail(const Detail& rhs)
  55.         : id(rhs.id), mass(rhs.mass), name(rhs.name)
  56.     { }
  57.  
  58.     ~Detail() { }
  59.  
  60.     friend std::istream& operator>>(std::istream& is, Detail& detail)
  61.     {
  62.         is >> detail.id >> detail.mass >> detail.name;
  63.         return is;
  64.     }
  65.  
  66.     friend std::ostream& operator<<(std::ostream& os, const Detail& detail)
  67.     {
  68.         os << detail.id << " " << detail.mass << " " << detail.name << "\n";
  69.         return os;
  70.     }
  71.  
  72.     Detail& operator=(const Detail& rhs)
  73.     {
  74.         if (this != &rhs)
  75.         {
  76.             id = rhs.id;
  77.             mass = rhs.mass;
  78.             name = rhs.name;
  79.         }
  80.  
  81.         return *this;
  82.     }
  83.  
  84.     std::fstream& write(std::fstream& file)
  85.     {
  86.         if (!file.is_open())
  87.         {
  88.             throw std::invalid_argument("Attempt to read from closed file");
  89.         }
  90.  
  91.         file.write(reinterpret_cast<char*>(&id), sizeof(int));
  92.         file.write(reinterpret_cast<char*>(&mass), sizeof(float));
  93.  
  94.         auto str_size = name.size();
  95.         file.write(reinterpret_cast<char*>(&str_size), sizeof(str_size));
  96.        
  97.         file.write(&name[0], str_size);
  98.  
  99.         return file;
  100.     }
  101.  
  102.     std::fstream& read(std::fstream& file)
  103.     {
  104.         if (!file.is_open())
  105.         {
  106.             throw std::invalid_argument("Attempt to write to closed file");
  107.         }
  108.  
  109.         if (!check_file(file)) // if eof was reached
  110.         {
  111.             file.setstate(file.rdstate() | file.failbit);
  112.             return file;
  113.         }
  114.  
  115.         file.read(reinterpret_cast<char*>(&id), sizeof(int));
  116.         file.read(reinterpret_cast<char*>(&mass), sizeof(float));
  117.            
  118.         std::string::size_type str_size;
  119.         file.read(reinterpret_cast<char*>(&str_size), sizeof(str_size));
  120.  
  121.         name.resize(str_size);
  122.         file.read(&name[0], str_size);
  123.  
  124.         return file;
  125.     }
  126.  
  127.     std::fstream& cwrite(std::fstream& file)
  128.     {
  129.         if (!file.is_open())
  130.         {
  131.             throw std::invalid_argument("Attempt to write to a closed file");
  132.         }
  133.  
  134.         write_string(file, std::to_string(id));
  135.         write_string(file, ftos(mass));
  136.         write_string(file, name, '\n');
  137.  
  138.         return file;
  139.     }
  140.  
  141.     std::fstream& cread(std::fstream& file)
  142.     {
  143.         if (!file.is_open())
  144.         {
  145.             throw std::invalid_argument("Attempt to read from closed file");
  146.         }
  147.  
  148.         if (!check_file(file))
  149.         {
  150.             file.setstate(file.rdstate() | file.failbit);
  151.             return file;
  152.         }
  153.        
  154.         id = std::stoi(read_string(file));
  155.         mass = std::stof(read_string(file));
  156.         name = read_string(file);
  157.  
  158.         return file;
  159.     }
  160.  
  161.     const float get_mass() const { return mass; }
  162.     const std::string get_name() const { return name; }
  163.     const int get_id() const { return id; }
  164.  
  165.     void set_id(int i) { id = i; }
  166.     void set_mass(float m) { mass = m; }
  167.     void set_name(const std::string& n) { name = n; }
  168.  
  169. private:
  170.     std::string read_string(std::fstream& file)
  171.     {
  172.         std::string str;
  173.         char ch;
  174.  
  175.         while (1)
  176.         {
  177.             ch = file.get();
  178.  
  179.             if (ch == ' ' || ch == '\t' || ch == '\n' || file.eof())
  180.             {
  181.                 break;
  182.             }
  183.  
  184.             str += ch;
  185.         }
  186.  
  187.         return str;
  188.     }
  189.  
  190.     std::fstream& write_string(std::fstream& file, const std::string& str, char delim = ' ')
  191.     {
  192.         for (auto i : str)
  193.         {
  194.             file.put(i);
  195.         }
  196.         file.put(delim);
  197.  
  198.         return file;
  199.     }
  200.  
  201.     int id;
  202.     float mass;
  203.     std::string name;
  204. };
  205.  
  206. std::istream& operator>>(std::istream&, Detail&);
  207.  
  208. std::ostream& operator<<(std::ostream&, const Detail&);
  209.  
  210. bool operator==(const Detail& lhs, const Detail& rhs)
  211. {
  212.     return lhs.get_id() == rhs.get_id() && lhs.get_mass() == rhs.get_mass() && lhs.get_name() == rhs.get_name();
  213. }
  214.  
  215. bool operator!=(const Detail& lhs, const Detail& rhs)
  216. {
  217.     return !(lhs == rhs);
  218. }
  219.  
  220. void reverse_output(std::fstream& file, int mode)
  221. {
  222.     if (!file.is_open())
  223.     {
  224.         throw std::invalid_argument("Attempt to read from empty file");
  225.     }
  226.  
  227.     file.seekg(-3, std::ios::end);
  228.     std::ios::streampos pos = file.tellg();
  229.     Detail det;
  230.  
  231.     while (pos > 0)
  232.     {
  233.         for (char ch = file.get();
  234.             pos > 0 && ch != '\n';
  235.             ch = file.get())
  236.         {
  237.             if (ch != '\n')
  238.             {
  239.                 pos -= 1;          
  240.                 file.seekg(pos);
  241.             }
  242.         }
  243.  
  244.         if (!pos) file.seekg(pos);
  245.  
  246.         mode ? file >> det : det.cread(file);
  247.  
  248.         std::cout << det;
  249.  
  250.         if (pos)
  251.         {
  252.             pos -= 2;
  253.             file.seekg(pos);
  254.         }
  255.     }
  256. }
  257.  
  258. std::vector<Detail> find_by_id(std::fstream& file, int id, int mode)
  259. {
  260.     if (!file.is_open())
  261.     {
  262.         throw std::invalid_argument("Trying to search in the closed file");
  263.     }
  264.  
  265.     file.seekg(0, std::ios::beg);
  266.  
  267.     std::vector<Detail> details;
  268.     Detail det;
  269.  
  270.     while (check_file(file))
  271.     {
  272.         switch (mode)
  273.         {
  274.         case 0:
  275.             file >> det;
  276.             break;
  277.         case 1:
  278.             det.cread(file);
  279.             break;
  280.         case 2:
  281.             det.read(file);
  282.             break;
  283.         default:
  284.             break;
  285.         }
  286.  
  287.         if (det.get_id() == id)
  288.         {
  289.             details.emplace_back(det);
  290.         }
  291.     }
  292.  
  293.     return details;
  294. }
  295.  
  296. void search(std::fstream& file, int id, int mode)
  297. {
  298.     std::vector<Detail> details = find_by_id(file, id, mode);
  299.  
  300.     if (!details.empty())
  301.     {
  302.         for (auto i : details)
  303.         {
  304.             std::cout << i << "\n";
  305.         }
  306.     }
  307.     else
  308.     {
  309.         std::cout << "Детали с данным id = " << id << " не найдены!" << std::endl;
  310.     }
  311. }
  312.  
  313. std::string ftos(float x)
  314. {
  315.     std::string str = boost::lexical_cast<std::string>(x);
  316.  
  317.     for (auto i : str)
  318.     {
  319.         if (i == ',')
  320.         {
  321.             i = '.';
  322.             break;
  323.         }
  324.     }
  325.  
  326.     return str;
  327. }
  328.  
  329. void shift(std::fstream& file, std::ios::streampos p, const std::string& filename, int mode)
  330. {
  331.     Detail det;
  332.     file.seekg(p);
  333.  
  334.     while (!file.eof())
  335.     {
  336.         p = file.tellg();
  337.  
  338.         if (!check_file(file) || file.eof())
  339.         {
  340.             break;
  341.         }
  342.  
  343.         mode ? file >> det : det.read(file);
  344.  
  345.         if (!check_file(file) || file.eof())
  346.         {
  347.             if (file.eof() || file.fail())
  348.             {
  349.                 file.clear();
  350.             }
  351.  
  352.             std::experimental::filesystem::resize_file(filename, p);
  353.             file.seekg(std::ios::beg);
  354.             break;
  355.         }
  356.  
  357.         mode ? file >> det : det.read(file);
  358.  
  359.         if (p)
  360.         {
  361.             p += 1;
  362.         }
  363.  
  364.         file.seekg(p);
  365.         mode ? file << det : det.write(file);
  366.     }
  367. }
  368.  
  369. void remove(const Detail& det, std::fstream& file, const std::string& filename, int mode, std::ios::openmode openmode)
  370. {
  371.     std::vector<Detail> details;
  372.     int count = 0;
  373.     Detail d;
  374.     file.seekg(std::ios::beg);
  375.  
  376.     while (1)
  377.     {
  378.         mode ? file >> d : d.read(file);
  379.  
  380.         count++;
  381.  
  382.         if (d != det)
  383.         {
  384.             details.emplace_back(d);
  385.         }
  386.  
  387.         if (!check_file(file))
  388.         {
  389.             break;
  390.         }
  391.     }
  392.  
  393.     file.clear();
  394.     file.close();
  395.     file.open(filename.c_str(), openmode | std::ios::trunc);
  396.     file.seekg(std::ios::beg);
  397.  
  398.     for (auto i : details)
  399.     {
  400.         mode ? file << i : i.write(file);
  401.     }
  402.  
  403.     std::cout << "Удално " << count - details.size() << " объетов" << std::endl;
  404. }
  405.  
  406. float get_float(std::istream& is)
  407. {
  408.     float f;
  409.  
  410.     while (!(is >> f))
  411.     {
  412.         std::cout << "Ошибка ввода! Введите число с плавающей точкой!" << std::endl;
  413.         std::cin.clear();
  414.         std::cin.ignore(static_cast<std::streamsize>(std::numeric_limits<int>::max()), '\n');
  415.     }
  416.  
  417.     return f;
  418. }
  419.  
  420. int get_int()
  421. {
  422.     int i;
  423.  
  424.     while (!(std::cin >> i))
  425.     {
  426.         std::cout << "Ошибка ввода! Введите целое число!" << std::endl;
  427.         std::cin.clear();
  428.         std::cin.ignore(static_cast<std::streamsize>(std::numeric_limits<int>::max()), '\n');
  429.     }
  430.  
  431.     return i;
  432. }
  433.  
  434. Detail get_detail(std::istream& is)
  435. {
  436.     Detail det;
  437.  
  438.     det.set_id(get_int());
  439.    
  440.     float mass;
  441.     do
  442.     {
  443.         mass = get_float(is);
  444.         if (mass <= 0)
  445.         {
  446.             std::cout << "Введите положительное значение\n";
  447.         }
  448.     } while (mass <= 0);
  449.  
  450.     det.set_mass(mass);
  451.  
  452.     std::string name;
  453.     is >> name;
  454.  
  455.     det.set_name(name);
  456.  
  457.     return det;
  458. }
  459.  
  460. void menu()
  461. {
  462.     std::cout  << "Выберите действие:" << std::endl << std::endl;
  463.     std::cout << std::setw(50) << std::left << "1)Создать деталь " << "8)Вывод содержимого текстового файла в обратном порядке\n";
  464.     std::cout << std::setw(50) << std::left << "2)Запись детали в текстовый файn " << "9)Посивольный вывод текстового файла в обратном порядке\n";
  465.     std::cout << std::setw(50) << std::left << "3)Запись детали в бинарный файл " << "10)Поиск записей по id в тектсовом файле\n";
  466.     std::cout << std::setw(50) << std::left << "4)Запись детали в текстовый файл посимвольно " << "11)Поиск записей по id в тектсовом файле(посимвольное считывание)\n";
  467.     std::cout << std::setw(50) << std::left << "5)Вывод содержимого текстового файла " << "12)Поиск записей по id в бинарном файле\n";
  468.     std::cout << std::setw(50) << std::left << "6)Посимвольный вывод содержимого текстового файла " << "13)Удаление записиси из текстового файла\n";
  469.     std::cout << std::setw(50) << std::left << "7)Вывод содержимого бинарного файла " << "14)Удаление записиси из бинарного файла\n";
  470.     std::cout << std::setw(50) << std::left << "0)Закончить " << "15)Очистить экран\n";
  471. }
  472.  
  473. int choose()
  474. {
  475.     int i;
  476.  
  477.     while (1)
  478.     {
  479.         i = get_int();
  480.  
  481.         if (i > 15 || i < 0)
  482.         {
  483.             std::cout << "Некорректный ввод!" << std::endl;;
  484.         }
  485.         else
  486.         {
  487.             break;
  488.         }
  489.     }
  490.  
  491.     return i;
  492. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement