Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.49 KB | None | 0 0
  1. #include "stdlib.h"
  2. #include <conio.h>
  3. #include <cstring>
  4. #include <ctime>
  5. #include <iomanip>
  6. #include <iostream>
  7. #include <fstream>
  8. #include <string>
  9.  
  10. #define nl printf("\n")
  11. // Сравнение дат
  12. bool timeCompare(std::tm Bought, int ShelfLife, std::tm Sold)
  13. {
  14.   Bought.tm_hour += ShelfLife;
  15.   time_t t1 = mktime(&Bought);
  16.   time_t t2 = mktime(&Sold);
  17.   if (t1 == -1 || t2 == -1) return false;
  18.   if (t1 >= t2)
  19.     {
  20.       // Если первая дата больше или равна второй - возвращаем true
  21.       return true;
  22.     }
  23.   else return false;
  24. }
  25.  
  26. // Односвязный список
  27. typedef struct Buy {
  28.   char vendorCode[9];           //Артикул
  29.   int bought;                   //Купили
  30.   std::tm Date = {};            //Дата покупки дд:мм:гг
  31.   struct Buy *next;         //Ссылка на следующий элемент списка
  32. } Buy;
  33. // Добавление элемента в конец
  34. void push(Buy **head, char VendorCode[9], int Bought, std::tm Date) {
  35.  
  36.   Buy *tmp = *head;                             //Создаём временный элемент для прохождения по head
  37.   Buy *next = (Buy*)malloc(sizeof(Buy));        //Создаём контейнер для "следующего" элемента
  38.  
  39.   memcpy(next->vendorCode, VendorCode, 9);      //Заполняем next
  40.   next->bought = Bought;                        //Заполняем next
  41.   next->Date = Date;
  42.   next->next = nullptr;
  43.  
  44.   if (*head == nullptr)                         //Если элемент первый, то
  45.     {
  46.       (*head) = next;                                   //Первый элемент равен next
  47.     }
  48.   else {                                            //Иначе
  49.       while (tmp->next != nullptr)                  //Проходим по tmp, пока уществует следующий элемент
  50.         {
  51.           tmp = tmp->next;
  52.         }
  53.       tmp->next = next;                             //Когда следующий элемент равен NULL (т.е. сейчас мы на последнем элементе в tmp) меняем значение следующего на next
  54.     }
  55. }
  56. // Удаление элемента с VendorCode
  57. int pop(Buy **head, char VendorCode[9])
  58. {
  59.   if (!head) return -1;
  60.   Buy *prev = nullptr;
  61.   Buy *current = (*head);
  62.   while (current)
  63.     {
  64.       if (strcmp(current->vendorCode, VendorCode) == 0) {
  65.           if (current == (*head)) {
  66.               (*head) = current->next;
  67.             }
  68.           else {
  69.               prev->next = current->next;
  70.             }
  71.           break;
  72.         }
  73.       if (!(current->next)) return -1;
  74.       prev = current;
  75.       current = current->next;
  76.     }
  77.   return 1;
  78. }
  79. // Чтение из файла
  80. int fscan(const char *name, Buy **head)
  81. {
  82.   char line[256];
  83.   std::ifstream ifs(name);
  84.   if (!ifs) return -1;
  85.   while (ifs.getline(line, 256)) {
  86.       char VendorCode[9];
  87.       int Bought;
  88.       std::tm Date = {};
  89.       sscanf(line, "%8s %d %d/%d/%d", VendorCode, &Bought, &Date.tm_mday, &Date.tm_mon, &Date.tm_year);
  90.       Date.tm_mon--;
  91.       Date.tm_year -= 1900;
  92.       push(&(*head), VendorCode, Bought, Date);
  93.     }
  94.   ifs.close();
  95.   return 1;
  96. }
  97. // Запись в файл
  98. void fprint(const char *name, Buy *head)
  99. {
  100.   std::ofstream ofs(name);
  101.   Buy *last = head;
  102.   do                        //Пока существует список
  103.     {
  104.       ofs << last->vendorCode << " " << last->bought << " " << std::put_time(&last->Date, "%d/%m/%Y") << std::endl;
  105.       last = last->next;                    //Перевод указателя
  106.       nl;
  107.     } while (last != head);
  108.   ofs.close();
  109. }
  110. // Чтение с консоли
  111. void scan(Buy **head)
  112. {
  113.   char VendorCode[9]{};
  114.   int InStock;
  115.   std::tm Date = {};
  116.   std::cout << "Введите артикул: ";
  117.   std::cin >> VendorCode;
  118.   nl;
  119.   std::cout << "Введите сколько поступило на склад: ";
  120.   std::cin >> InStock;
  121.   nl;
  122.   std::cout << "Введите дату поступлления на склад: ";
  123.   std::cin >> std::get_time(&Date, "%d/%m/%Y");
  124.   nl;
  125.   nl;
  126.   push(&(*head), VendorCode, InStock, Date);
  127. }
  128. // Вывод на консоль
  129. void print(Buy *head)
  130. {
  131.   if (!head) return;                        //Если не существует списка - выходим
  132.   Buy *last = head;
  133.   do                        //Пока существует список
  134.     {
  135.       printf("%s ", last->vendorCode);  //Вывод
  136.       printf("%d ", last->bought);      //Вывод
  137.       std::cout << std::put_time(&last->Date, "%d/%m/%Y");
  138.       last = last->next;                    //Перевод указателя
  139.       nl;
  140.     } while (last != nullptr);
  141. }
  142. // Удаление слишком новых записей
  143. void toDate(Buy **head, std::tm time)
  144. {
  145.   Buy *current = (*head);
  146.   int cout = 0;
  147.  
  148.   do
  149.     {
  150.       current = current->next;
  151.       cout++;
  152.     } while (current != nullptr);
  153.   current = *head;
  154.   do
  155.     {
  156.       if (!timeCompare(time, 0, current->Date))
  157.         {
  158.           pop(head, current->vendorCode);
  159.         }
  160.       else
  161.         {
  162.           current = current->next;
  163.         }
  164.       cout--;
  165.     } while (cout != 0);
  166. }
  167.  
  168. // Кольцевой список
  169. typedef struct Stock
  170. {
  171.   char vendorCode[9];           //Артикул
  172.   int inStock;              //Осталось на складе
  173.   std::tm Date = {};            //Дата поступления дд:мм:гг
  174.   int shelfLife;                //Срок годности
  175.   struct Stock *next;           //Ссылка на следующий элемент списка
  176. } Stock;
  177. // Добавление элемента в конец
  178. void push(Stock **head, const char VendorCode[9], int InStock, std::tm Date, int ShelfLife) {
  179.  
  180.   Stock *tmp = *head;                               //Создаём временный элемент для прохождения по head
  181.   Stock *next = (Stock*)malloc(sizeof(Stock));      //Создаём контейнер для "следующего" элемента
  182.  
  183.   memcpy(next->vendorCode, VendorCode, 9);      //Заполняем next
  184.   next->inStock = InStock;                      //Заполняем next
  185.   next->Date = Date;
  186.   next->shelfLife = ShelfLife;                  //Заполняем next
  187.  
  188.   if (*head == nullptr)                         //Если элемент первый, то
  189.     {
  190.       (*head) = next;                                   //Первый элемент равен next
  191.     }
  192.   else {                                            //Иначе
  193.       while (tmp->next != (*head))                  //Проходим по tmp, пока уществует следующий элемент
  194.         {
  195.           tmp = tmp->next;
  196.         }
  197.       tmp->next = next;                             //Когда следующий элемент равен NULL (т.е. сейчас мы на последнем элементе в tmp) меняем значение следующего на next
  198.     }
  199.   next->next = (*head);                         //Т.к. элемент вставляется в конце, то следующий элемент за последним равен NULL
  200. }
  201. // Удаление элемента с VendorCode
  202. int pop(Stock **head, char VendorCode[9])
  203. {
  204.   Stock *current, *prev;
  205.   prev = nullptr;
  206.   current = (*head);
  207.   do
  208.     {
  209.       prev = current;
  210.       current = current->next;
  211.     } while (current != (*head));
  212.   while (current)
  213.     {
  214.       if (strcmp(current->vendorCode, VendorCode) == 0) {
  215.           prev->next = current->next;
  216.           if (current == *head)
  217.             {
  218.               *head = prev->next;
  219.             }
  220.           break;
  221.         }
  222.       prev = current;
  223.       current = current->next;
  224.     }
  225.   return 1;
  226. }
  227. // Проверяет, хватит ли товара
  228. int isEnought(Stock **s_head, Buy *b_head)
  229. {
  230.   Stock *current;
  231.   current = *s_head;
  232.   int cout = 0;
  233.  
  234.   do
  235.     {
  236.       current = current->next;
  237.       cout++;
  238.     } while (current != *s_head);
  239.  
  240.   int inStock = 0;
  241.   do
  242.     {
  243.       if (strcmp((*s_head)->vendorCode, b_head->vendorCode) == 0 && timeCompare(b_head->Date, 0, (*s_head)->Date) && timeCompare((*s_head)->Date, (*s_head)->shelfLife, b_head->Date))
  244.         {
  245.           inStock += (*s_head)->inStock;
  246.           (*s_head) = (*s_head)->next;
  247.         }
  248.       else
  249.         {
  250.           if (!strcmp((*s_head)->vendorCode, b_head->vendorCode) == 0)
  251.             {
  252.               (*s_head) = (*s_head)->next;
  253.             }
  254.           else
  255.             {
  256.               if (strcmp((*s_head)->vendorCode, b_head->vendorCode) == 0 && (!timeCompare(b_head->Date, 0, (*s_head)->Date) || !timeCompare((*s_head)->Date, (*s_head)->shelfLife, b_head->Date)))
  257.                 {
  258.                   pop(&(*s_head), b_head->vendorCode);
  259.                 }
  260.             }
  261.         }
  262.       cout--;
  263.     } while (cout != 0);    //Проходим по списку и считаем количество всех элементов с VendorCode
  264.   return inStock >= b_head->bought ? 1 : -1;
  265. }
  266. // Покупка со склада
  267. int buy(Stock **head, char VendorCode[9], int bought)
  268. {
  269.   if (!head) return -1;                                       //Если не существует списка - выходим
  270.   Stock *current = (*head);                                   //Ячейка "текущего" элемента
  271.   do                                          //Пока существует текущий элемент
  272.     {
  273.       if (strcmp(current->vendorCode, VendorCode) == 0) {     //Сравниваем строки
  274.           int delta = current->inStock - bought;
  275.           int result = 1;
  276.           if (delta > 0)
  277.             {
  278.               current->inStock -= bought;
  279.               return 0;
  280.             }
  281.           if (delta == 0)
  282.             {
  283.               result = pop(head, VendorCode);
  284.               return result == 1 ? 0 : -1;
  285.             }
  286.           if (delta < 0)
  287.             {
  288.               result = buy(&(current->next), VendorCode, -delta);
  289.               if (result == -1) return -1;
  290.               if (result == 0) result = pop(head, VendorCode);
  291.               if (result == -1) return -1;
  292.             }
  293.         }
  294.       current = current->next;                                //Обновляем текущий элемент
  295.     } while (current != (*head));
  296.   return 1;
  297. }
  298. // Чтение из файла
  299. int fscan(const char *name, Stock **head)
  300. {
  301.   char line[256]{};
  302.   std::ifstream ifs(name);
  303.   if (!ifs) return -1;
  304.   while (ifs.getline(line, 256)) {
  305.       char VendorCode[9];
  306.       int InStock;
  307.       std::tm Date = {};
  308.       int ShelfLife;
  309.       sscanf(line, "%8s %d %d/%d/%d %d", VendorCode, &InStock, &Date.tm_mday, &Date.tm_mon, &Date.tm_year, &ShelfLife);
  310.       Date.tm_mon--;
  311.       Date.tm_year -= 1900;
  312.       push(&(*head), VendorCode, InStock, Date, ShelfLife);
  313.     }
  314.   ifs.close();
  315.   return 1;
  316. }
  317. // Запись в файл
  318. void fprint(const char *name, Stock *head)
  319. {
  320.   std::ofstream ofs(name);
  321.   Stock *last = head;
  322.   do                        //Пока существует список
  323.     {
  324.       ofs << last->vendorCode << " " << last->inStock << " " << last->shelfLife << " " <<  std::put_time(&last->Date, "%d/%m/%Y") << std::endl;
  325.       last = last->next;                    //Перевод указателя
  326.       nl;
  327.     } while (last != head);
  328.   ofs.close();
  329. }
  330. // Чтение с консоли
  331. void scan(Stock **head)
  332. {
  333.   char VendorCode[9]{};
  334.   int InStock;
  335.   std::tm Date = {};
  336.   int ShelfLife;
  337.   std::cout << "Введите артикул: ";
  338.   std::cin >> VendorCode;
  339.   nl;
  340.   std::cout << "Введите сколько поступило на склад: ";
  341.   std::cin >> InStock;
  342.   nl;
  343.   std::cout << "Введите дату поступлления на склад: ";
  344.   std::cin >> std::get_time(&Date, "%d/%m/%Y");
  345.   nl;
  346.   std::cout << "Введите срок годности в часах: ";
  347.   std::cin >> ShelfLife;
  348.   nl;
  349.   push(&(*head), VendorCode, InStock, Date, ShelfLife);
  350. }
  351. // Вывод на консоль.
  352. void print(Stock *head)
  353. {
  354.   if (!head) return;                        //Если не существует списка - выходим
  355.   Stock *last = head;
  356.   do                        //Пока существует список
  357.     {
  358.       printf("%s ", last->vendorCode);  //Вывод
  359.       printf("%d ", last->inStock);     //Вывод
  360.       printf("%d ", last->shelfLife);       //Вывод
  361.       std::cout << std::put_time(&last->Date, "%d/%m/%Y");
  362.       last = last->next;                    //Перевод указателя
  363.       nl;
  364.     } while (last != head);
  365. }
  366. // Удаление слишком новых записей
  367. void toDate(Stock **head, std::tm time)
  368. {
  369.   Stock *current = (*head);
  370.   int cout = 0;
  371.  
  372.   do
  373.     {
  374.       current = current->next;
  375.       cout++;
  376.     } while (current != *head);
  377.   do
  378.     {
  379.       if (!timeCompare(time, 0, (*head)->Date))
  380.         {
  381.           pop(&(*head), (*head)->vendorCode);
  382.         }
  383.       else
  384.         {
  385.           *head = (*head)->next;
  386.         }
  387.       cout--;
  388.     } while (cout != 0);
  389. }
  390. void Sort(Stock **head)
  391. {
  392.   Stock *prev = nullptr;
  393.   Stock *current = (*head);
  394.   Stock *next = (*head)->next;
  395.   int count = 0;
  396.   do
  397.     {
  398.       prev = current;
  399.       current = next;
  400.       next = next->next;
  401.       count++;
  402.  
  403.     } while (current != (*head));
  404.  
  405.   for (int i = 0; i < count; i++)
  406.     {
  407.       for(int j = 0; j < count - 1; j++)
  408.         {
  409.           if (!timeCompare((*head)->Date, 0, next->Date))
  410.             {
  411.               prev->next = next;
  412.               (*head)->next = next->next;
  413.               next->next = (*head);
  414.               prev = next;
  415.               next = (*head)->next;
  416.             } else
  417.             {
  418.               prev = (*head);
  419.               (*head) = next;
  420.               next = next->next;
  421.             }
  422.         }
  423.       print(*head);
  424.       nl;
  425.     }
  426. }
  427. // Анализ склада
  428. int analyze(Stock **stockList, Buy **buyList, std::tm time)
  429. {
  430.   toDate(&(*stockList), time);
  431.   while (buyList != nullptr)
  432.     {
  433.       if (!timeCompare(time, 0, (*buyList)->Date)) return 1;
  434.       if (isEnought(&(*stockList), (*buyList)) == 1)
  435.         {
  436.           if (buy(&(*stockList), (*buyList)->vendorCode, (*buyList)->bought) == -1) return -1;
  437.         }
  438.       else return -1;
  439.       (*buyList) = (*buyList)->next;
  440.     }
  441.   return 1;
  442. }
  443.  
  444. int main()
  445. {
  446.   setlocale(LC_ALL, "Russian");
  447.   //system("chcp 65001");
  448.  
  449.   Stock *stockList = nullptr; //Создаем NULL-список склада
  450.   Buy *buyList = nullptr;     //Создает NULL-список покупок
  451.  
  452.   std::tm time = {};
  453.  
  454.   fscan("Stock.txt", &stockList);
  455.   // Считывание и вывод склада
  456.   fscan("Buy.txt", &buyList);
  457.   // Считывание и вывод покупок
  458.  
  459.   char v = '1';
  460.   bool b = true;//Переменная для switch
  461.   bool o = false;
  462.   while (true)
  463.     {
  464.       switch (v)
  465.         {
  466.         case '0':
  467.           {
  468.             b = false;
  469.             break;
  470.           }
  471.         case '1':
  472.           {
  473.             printf("0. Выход\n1. Показать меню\n2. Покупки на склад\n3. Покупки со склада\n4. Анализ склада\n5. Ввод даты\n6. Добавить товар на склад\n7. Купить товар со склада\n8. Сортировка по времени\n");
  474.             break;
  475.           }
  476.         case '2':
  477.           {
  478.             std::cout << "Покупки на склад: " << std::endl;
  479.             print(stockList);
  480.             nl;
  481.             break;
  482.           }
  483.         case'3':
  484.           {
  485.             std::cout << "Покупки со склада: " << std::endl;
  486.             print(buyList);
  487.             nl;
  488.             break;
  489.           }
  490.         case'4':
  491.           {
  492.             if (!o) break;
  493.             std::cout << "Анализ склада на " << std::put_time(&time, "%d/%m/%Y") << ": " << std::endl;
  494.             //Sort(&stocklist);
  495.             //Sort(&buylist);
  496.             analyze(&stockList, &buyList, time);
  497.             print(stockList);
  498.             fprint("Analyze.txt", stockList);
  499.             nl;
  500.             break;
  501.           }
  502.         case'5':
  503.           {
  504.             printf("Введите дату для анализа склада (дд/мм/гг): ");
  505.             std::cin >> std::get_time(&time, "%d/%m/%Y");
  506.             o = true;
  507.             break;
  508.           }
  509.         case '6':
  510.           {
  511.             scan(&stockList);
  512.             break;
  513.           }
  514.         case '7':
  515.           {
  516.             scan(&buyList);
  517.             break;
  518.           }
  519.         case'8':
  520.           {
  521.             Sort(&stockList);
  522.             break;
  523.           }
  524.         default:
  525.           {
  526.             printf("Ошибка ввода.\n");
  527.             break;
  528.           }
  529.         }
  530.       if (!b) break;
  531.       std::cout << "Введите пункт меню: ";
  532.       std::cin >> v;
  533.       nl;
  534.     }
  535.   return 0;
  536. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement