Advertisement
coplantie

#labajivi

Dec 9th, 2019
604
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.17 KB | None | 0 0
  1. #define _CRTDBG_MAP_ALLOC
  2. #include <crtdbg.h>
  3. #include <memory.h>
  4. #include <stdio.h>
  5. #include <clocale>
  6. #include <cstdlib>
  7. #include <string>
  8. #include <conio.h>
  9. #include <windows.h>
  10.  
  11. //Из 5 лабы
  12. void CopyString(char*& tmp, char*& String, int lenght, bool Creating)
  13. {
  14.     if (Creating)
  15.     {
  16.         tmp = new char[lenght];
  17.     }
  18.     for (int index = 0; index < lenght; index++)
  19.     {
  20.         tmp[index] = String[index];
  21.     }
  22. }
  23.  
  24. void PushString(int& sizeString, char*& String, char last)
  25. {
  26.     char* tmpStr = new char[sizeString + 1];
  27.     CopyString(tmpStr, String, sizeString, false);
  28.     delete[] String;
  29.     String = tmpStr;
  30.     sizeString++;
  31.     String[sizeString - 1] = last;
  32. }
  33.  
  34. void PopString(int& sizeString, char*& String)
  35. {
  36.     if (sizeString > 0)
  37.     {
  38.         sizeString--;
  39.         char* tmpStr;
  40.         CopyString(tmpStr, String, sizeString, true);
  41.         delete[] String;
  42.         String = tmpStr;
  43.     }
  44. }
  45.  
  46. void EnterString(int& sizeString, char*& String)
  47. {
  48.     char buf = 0; //Введенный символ (ввод до enter)
  49.     while (true)
  50.     {
  51.         buf = _getch();
  52.         switch (buf)
  53.         {
  54.         case 13:
  55.         {
  56.             PushString(sizeString, String, '\0');
  57.             printf("\n");
  58.             return;
  59.         }
  60.         case 8:
  61.         {
  62.             if (sizeString > 0)//Чтобы не стереть фразу (до) на той же строке, где и ввод
  63.             {
  64.                 printf("\b");
  65.                 printf(" ");
  66.                 printf("\b");
  67.             }
  68.             PopString(sizeString, String);
  69.             break;
  70.         }
  71.         default:
  72.         {
  73.             PushString(sizeString, String, buf);
  74.             printf("%c", buf); // Так как нет эхо
  75.             break;
  76.         }
  77.         }
  78.     }
  79. }
  80.  
  81. void EnterFileString(FILE* inputFile, int& sizeString, char*& String)
  82. {
  83.     char buf = 0; //Введенный символ (ввод до enter)
  84.  
  85.     while (true)
  86.     {
  87.         buf = fgetc(inputFile);
  88.         switch (buf)
  89.         {
  90.         case EOF:
  91.         case ' ':
  92.         case 10:
  93.         {
  94.             if ((buf == 10) && (sizeString == 0))
  95.             {
  96.                 continue; //Лишние enter
  97.             }
  98.             PushString(sizeString, String, '\0');
  99.             return;
  100.         }
  101.         default:
  102.         {
  103.             PushString(sizeString, String, buf);
  104.             break;
  105.         }
  106.         }
  107.     }
  108. }
  109.  
  110. void PushVector(int& sizeVector, int*& Vector, int num)
  111. {
  112.     int* tmp = new int[sizeVector + 1];
  113.     for (int index = 0; index < sizeVector; index++)
  114.     {
  115.         tmp[index] = Vector[index];
  116.     }
  117.     delete[] Vector;
  118.     Vector = tmp;
  119.     sizeVector++;
  120.     Vector[sizeVector - 1] = num;
  121. }
  122. //Здесь заканчиваются функции из 5 лабы
  123.  
  124. //Функция для ввода значения, с проверкой принадлежности заданному диапазону
  125. //const char*, так как заранее заданная строка
  126.  
  127. int correctScanf(int min, int max, const char* text)
  128. {
  129.     int ret = 0;
  130.     while (true)
  131.     {
  132.         printf("%s: ", text);
  133.         scanf_s("%d", &ret);
  134.         if (ret < min)
  135.         {
  136.             printf("\nВведённые данные слишком малы\n");
  137.             continue; // начать с начала цикла (заново вводим)
  138.         }
  139.         else if (ret > max)
  140.         {
  141.             printf("\nВведённые данные слишком большие\n");
  142.             continue; // начать с начала цикла (заново вводим)
  143.         }
  144.         break;
  145.     }
  146.     return ret;
  147. }
  148.  
  149. int correctFileScanf(FILE* inputFile, int min, int max)
  150. {
  151.     int ret;
  152.     fscanf_s(inputFile, "%d", &ret);
  153.     if (ret < min) return min;
  154.     if (ret > max) return max;
  155.     return ret;
  156. }
  157.  
  158. struct Auto
  159. {
  160.     char* brand = nullptr;//марка
  161.     int sizeBrand = 0;// Размер строки, куда вводится название марки
  162.  
  163.     int date = 0;//дата выпуска
  164.     int volume = 0;//объем двигателя
  165.     int mileage = 0;//пробег
  166.      //+ есть поле сумма налога, которое вычисляется при необходимости
  167. };
  168.  
  169. struct Data
  170. {
  171.     Auto* cars = nullptr;
  172.     int size = 0;
  173. };
  174.  
  175. //Вычисляемое поле, налог на транспортное средство
  176. //[0;100] -> 7 | (100;250] -> 14 | (250;..) -> 30
  177. //Я написала формулы не сокращая, чтобы было понятно, откуда взялись числа
  178.  
  179. int getTax(int volume)
  180. {
  181.     int res = 0;
  182.     if (volume <= 100)
  183.         res = volume * 7;
  184.     else if (volume <= 250)
  185.         res = volume * 14;
  186.     else
  187.         res = 30 * volume;
  188.     return res;
  189. }
  190.  
  191. bool isEqual(Auto left, Auto right)
  192. {
  193.     if (strcmp(left.brand, right.brand) != 0) return false;
  194.     if (left.date != right.date) return false;
  195.     if (left.mileage != right.mileage) return false;
  196.     if (left.volume != right.volume) return false;
  197. }
  198.  
  199. bool comparisonAuto(Auto left, Auto right, int field)
  200. {
  201.     switch (field)
  202.     {
  203.     case 1:
  204.         if (left.date < right.date) return false;
  205.         break;
  206.     case 2:
  207.         if (left.volume < right.volume) return false;
  208.         break;
  209.     case 3:
  210.         if (left.mileage < right.mileage)   return false;
  211.         break;
  212.     case 4:
  213.         //Можно было бы и отсортировать по объему двигателя, так как чем он больше, тем больше и налог
  214.         //Функция налога строго возрастает
  215.         if (getTax(left.volume) < getTax(right.volume)) return false;
  216.         break;
  217.     default: // По умолчанию будет сортировка по марке
  218.  
  219.         if (strcmp(left.brand, right.brand) == -1) return false;
  220.         break;
  221.     }
  222.     return true;
  223. }
  224.  
  225. void CopyData(Data& buf, Data data, bool Creating)
  226. {
  227.     if (Creating)
  228.     {
  229.         buf.cars = new Auto[data.size];
  230.         buf.size = data.size;
  231.     }
  232.     for (int index = 0; index < data.size; ++index)
  233.     {
  234.         buf.cars[index] = data.cars[index];
  235.         CopyString(buf.cars[index].brand, data.cars[index].brand, data.cars[index].sizeBrand, true);
  236.     }
  237. }
  238.  
  239. void deleteAuto(Auto& cars)
  240. {
  241.     delete[] cars.brand;
  242.     cars.brand = nullptr;
  243.     cars.sizeBrand = 0;
  244.     cars.date = 0;
  245.     cars.mileage = 0;
  246.     cars.volume = 0;
  247. }
  248.  
  249. void deleteData(Data& data)
  250. {
  251.     for (int i = 0; i < data.size; ++i)
  252.     {
  253.         deleteAuto(data.cars[i]);
  254.     }
  255.     delete[] data.cars;
  256.     data.cars = nullptr;
  257.     data.size = 0;
  258. }
  259.  
  260. void deleteAllPosition(Data& data, int sizeVector, int* Vector)
  261. {
  262.     if (sizeVector == data.size)//Удаляем всё
  263.     {
  264.         deleteData(data);
  265.         return;
  266.     }
  267.     if (sizeVector == 0)
  268.     {
  269.         return; //Не нашли, что удалять
  270.     }
  271.     Data buf;
  272.     buf.size = data.size - sizeVector;
  273.     buf.cars = new Auto[buf.size];
  274.     int j = 0;
  275.     int l = 0;
  276.     for (int i = 0; i < data.size; ++i)
  277.     {
  278.         if (i != Vector[j])
  279.         {
  280.             buf.cars[l] = data.cars[i];
  281.             CopyString(buf.cars[l].brand, data.cars[i].brand, data.cars[i].sizeBrand, true);
  282.             ++l;
  283.         }
  284.         else
  285.         {
  286.             ++j;
  287.         }
  288.     }
  289.     deleteData(data);
  290.     data = buf;
  291. }
  292.  
  293. Auto inputOne(FILE* inputFile) //Если FILE* равен nullptr, будем считать, что работаем с консолью
  294. {
  295.     Auto ret;
  296.     if (inputFile != nullptr)
  297.     {
  298.         EnterFileString(inputFile, ret.sizeBrand, ret.brand);
  299.         ret.date = correctFileScanf(inputFile, 1800, 2019);
  300.         ret.volume = correctFileScanf(inputFile, 1, 10000);
  301.         ret.mileage = correctFileScanf(inputFile, 0, 10000000);
  302.     }
  303.     else
  304.     {
  305.         printf("\nВведите название марки: ");
  306.         EnterString(ret.sizeBrand, ret.brand);
  307.         ret.date = correctScanf(1800, 2019, "Введите дату выпуска машины: ");
  308.         ret.volume = correctScanf(1, 10000, "Введите объем двигателя машины: ");
  309.         ret.mileage = correctScanf(0, 10000000, "Введите пробег машины: ");
  310.     }
  311.     return ret;
  312. }
  313.  
  314. void BubbleSort(Data& data, int choice)//Сортировка пузырьком
  315. {
  316.     Auto buf;
  317.     int i = 0;
  318.     int j = 0;
  319.     for (i = 0; i < data.size; ++i)
  320.     {
  321.         for (j = 0; j < data.size - 1 - i; ++j) //До конца нет смысла доходить, так как 'пузырьки' всплывают
  322.         {
  323.             if (comparisonAuto(data.cars[j], data.cars[j + 1], choice))
  324.             {
  325.                 buf = data.cars[j];
  326.                 data.cars[j] = data.cars[j + 1];
  327.                 data.cars[j + 1] = buf;
  328.             }
  329.         }
  330.     }
  331. }
  332.  
  333. void outData(Data data)
  334. {
  335.     for (int i = 0; i < data.size; ++i)
  336.     {
  337.         printf("%d-я машина\n", i + 1);
  338.         printf("Марка машины: %s\n", data.cars[i].brand);
  339.         printf("Дата выпуска: %d\n", data.cars[i].date);
  340.         printf("Объём двигателя: %d\n", data.cars[i].volume);
  341.         printf("Пробег: %d\n", data.cars[i].mileage);
  342.         printf("Налог: %d\n\n", getTax(data.cars[i].volume));
  343.     }
  344. }
  345.  
  346. void outFileData(FILE* outputFile, Data data)
  347. {
  348.     fprintf(outputFile, "%d\n", data.size);
  349.     for (int i = 0; i < data.size; ++i)
  350.     {
  351.         fprintf(outputFile, "%s\n", data.cars[i].brand);
  352.         fprintf(outputFile, "%d\n", data.cars[i].date);
  353.         fprintf(outputFile, "%d\n", data.cars[i].volume);
  354.         fprintf(outputFile, "%d\n", data.cars[i].mileage);
  355.     }
  356. }
  357.  
  358. void output(Data& data, int choiceSort, bool withFile)
  359. {
  360.     FILE* outputFile = nullptr;
  361.     if (choiceSort >= 0)//Есть сортировка
  362.     {
  363.         BubbleSort(data, choiceSort);
  364.     }
  365.     if (withFile)
  366.     {
  367.         fopen_s(&outputFile, "in.txt", "w");
  368.         if (outputFile == NULL)
  369.         {
  370.             fprintf(stderr, "Не удалось открыть файл");
  371.         }
  372.         outFileData(outputFile, data);
  373.         fclose(outputFile);
  374.     }
  375.     else
  376.     {
  377.         outData(data);
  378.     }
  379. }
  380.  
  381. void input(Data& data, bool withFile)
  382. {
  383.     int i = 0;
  384.     int j = 0; // Чтобы записывать, начиная с середины (то есть дополнять массив)
  385.     int num = 0;
  386.     FILE* inputFile = nullptr;
  387.     if (withFile)
  388.     {
  389.         fopen_s(&inputFile, "in.txt", "r");
  390.         if (inputFile == NULL)
  391.         {
  392.             printf("Файл не найден!\n");
  393.             exit(0);
  394.         }
  395.         if (getc(inputFile) == EOF)
  396.         {
  397.             printf("Файл пуст!");
  398.             exit(0);
  399.         }
  400.         fclose(inputFile);
  401.         FILE* inputFile = nullptr;
  402.         fopen_s(&inputFile, "in.txt", "r");
  403.         num = correctFileScanf(inputFile, 0, 100000);
  404.     }
  405.     else
  406.     {
  407.         num = correctScanf(0, 100000, "Введите количество машин");
  408.     }
  409.     j = data.size;
  410.     Data buf;
  411.     CopyData(buf, data, true);
  412.     deleteData(data);
  413.     data.size = buf.size + num;
  414.     if (data.size > 0)
  415.     {
  416.         data.cars = new Auto[data.size];
  417.     }
  418.     CopyData(data, buf, false);
  419.     deleteData(buf);
  420.     for (i = 0; i < num; i++, j++)
  421.     {
  422.         data.cars[j] = inputOne(inputFile);
  423.     }
  424. }
  425.  
  426. void deleteData(Data& data, int choice)
  427. {
  428.     if (data.size == 0)
  429.     {
  430.         printf("\n-------   Массив пуст, удалять нечего -----\n");
  431.         return;
  432.     }
  433.  
  434.     int* whoIsDelete = nullptr;
  435.     int num = 0;
  436.     int i = 0;
  437.     int amount = 0;
  438.     Auto buf; //Для считывания, а потом поиска на соответствие
  439.     switch (choice)
  440.     {
  441.     case 0:
  442.     {
  443.         //Приводим к общему типу (якобы могло быть несколько удаляемых объектов
  444.         whoIsDelete = new int[1];
  445.         num = correctScanf(1, data.size, "Введите порядковый номер");
  446.         whoIsDelete[0] = num - 1;
  447.         amount = 1;
  448.         break;
  449.     }
  450.     case 1:
  451.     {
  452.         printf("\n Введите название марки :");
  453.         char* brand = nullptr;
  454.         int sizeBrand = 0;
  455.         EnterString(sizeBrand, brand);
  456.         for (i = 0; i < data.size; ++i)
  457.         {
  458.             if (strcmp(brand, data.cars[i].brand) == 0)
  459.             {
  460.                 PushVector(amount, whoIsDelete, i);
  461.             }
  462.         }
  463.         delete[] brand;
  464.         break;
  465.     }
  466.     case 2:
  467.     {
  468.         buf = inputOne(nullptr); // Всегда считываем с консоли
  469.         for (i = 0; i < data.size; ++i)
  470.         {
  471.             if (isEqual(buf, data.cars[i]))
  472.             {
  473.                 PushVector(amount, whoIsDelete, i);
  474.             }
  475.         }
  476.         deleteAuto(buf);
  477.         break;
  478.     }
  479.     }
  480.  
  481.     deleteAllPosition(data, amount, whoIsDelete);
  482.     delete[] whoIsDelete;
  483. }
  484.  
  485. void choiceDelete(Data& data)
  486. {
  487.     printf("\n Если хотите отменить, введите \"no\"\n если хотите продолжить, можете ввести любую строку :");
  488.     char* cancel = nullptr;
  489.     int size = 0;
  490.     EnterString(size, cancel);
  491.     if (strcmp(cancel, "no") != 0)
  492.     {
  493.         deleteData(data);
  494.     }
  495.     delete[] cancel;
  496. }
  497.  
  498. void menuSortData(Data& data)
  499. {
  500.     int choice = 0;
  501.     while (true)
  502.     {
  503.         printf("\n-------   Подменю сортировки данных  -----\n");
  504.         printf("0 - Удалить всё\n");
  505.         printf("1 - Отсортировать по названию марки\n");
  506.         printf("2 - Отсортировать по году выпуску\n");
  507.         printf("3 - Отсортировать по объёму двигателя\n");
  508.         printf("4 - Отсортировать по пробегу\n");
  509.         printf("5 - Отсортировать по сумме налога на т.с.\n");
  510.  
  511.         printf("8 - выйти из меню ввода данных\n");
  512.         scanf_s("%d", &choice);
  513.         switch (choice)
  514.         {
  515.         case 0:
  516.         {
  517.             choiceDelete(data);
  518.             break;
  519.         }
  520.         case 1:
  521.         case 2:
  522.         case 3:
  523.         case 4:
  524.         case 5:
  525.         {
  526.             BubbleSort(data, choice - 1);
  527.             break;
  528.         }
  529.         case 8:
  530.         {
  531.             return;
  532.         }
  533.         default:
  534.         {
  535.             printf("\n данной функции в программе нет\n");
  536.             break;
  537.         }
  538.         }
  539.     }
  540. }
  541.  
  542. void menuDeleteData(Data& data)
  543. {
  544.     int choice = 0;
  545.     while (true)
  546.     {
  547.         printf("\n-------   Подменю удаления данных  -----\n");
  548.         printf("0 - Удалить всё\n");
  549.         printf("1 - удалить сведения о машине по порядковому номеру в массиве (от единицы)\n");
  550.         printf("2 - удалить сведения всех машин указанной марки\n");
  551.         printf("3 - удалить сведения о машине по совпадению всех данных\n");
  552.  
  553.         printf("8 - выйти из меню ввода данных\n");
  554.         scanf_s("%d", &choice);
  555.         switch (choice)
  556.         {
  557.         case 0:
  558.         {
  559.             choiceDelete(data);
  560.             break;
  561.         }
  562.         case 1:
  563.         case 2:
  564.         case 3:
  565.         {
  566.             deleteData(data, choice - 1);
  567.             break;
  568.         }
  569.         case 8:
  570.         {
  571.             return;
  572.         }
  573.         default:
  574.         {
  575.             printf("\n данной функции в программе нет\n");
  576.             break;
  577.         }
  578.         }
  579.     }
  580. }
  581.  
  582. void menuOutputData(Data& data)
  583. {
  584.     int choice = 0;
  585.     while (true)
  586.     {
  587.         printf("\n-------   Подменю вывода данных  -----\n");
  588.         printf("0 - Удалить всё\n");
  589.         printf("1 - вывести данные на консоль (без сортировки)\n");
  590.         printf("2 - Отсортировать по названию марки (консоль)\n");
  591.         printf("3 - Отсортировать по году выпуску (консоль)\n");
  592.         printf("4 - Отсортировать по объёму двигателя (консоль)\n");
  593.         printf("5 - Отсортировать по пробегу (консоль)\n");
  594.         printf("6 - Отсортировать по сумме налога на т.с. (консоль)\n");
  595.  
  596.         printf("\n------------------\n");
  597.         printf("7 - вывести данные в файл (без сортировки)\n");
  598.         printf("8 - Отсортировать по названию марки (в файл)\n");
  599.         printf("9 - Отсортировать по году выпуску (в файл)\n");
  600.         printf("10 - Отсортировать по объёму двигателя (в файл)\n");
  601.         printf("11 - Отсортировать по пробегу (в файл)\n");
  602.         printf("12 - Отсортировать по сумме налога на т.с. (в файл)\n");
  603.  
  604.         printf("13 - выйти из меню вывода данных\n");
  605.  
  606.         scanf_s("%d", &choice);
  607.  
  608.         if (choice == 0)
  609.         {
  610.             choiceDelete(data);
  611.         }
  612.         else
  613.         {
  614.             if (choice <= 6)
  615.             {
  616.                 output(data, choice - 2, false);
  617.             }
  618.             else
  619.             {
  620.                 if (choice <= 12)
  621.                 {
  622.                     output(data, choice - 8, true);
  623.                 }
  624.                 else
  625.                 {
  626.                     if (choice == 13)
  627.                     {
  628.                         return;
  629.                     }
  630.                     printf("\n данной функции в программе нет\n");
  631.                 }
  632.             }
  633.         }
  634.     }
  635. }
  636.  
  637. void menuInputData(Data& data)
  638. {
  639.     int choice = 0;
  640.     while (true)
  641.     {
  642.         printf("\n-------   Подменю ввода данных  -----\n");
  643.         printf("0 - Удалить всё\n");
  644.         printf("1 - добавить данные с консоли в конец\n");
  645.         printf("2 - добавить данные с указанного файла в конец\n");
  646.         printf("8 - выйти из меню ввода данных\n");
  647.         scanf_s("%d", &choice);
  648.         switch (choice)
  649.         {
  650.         case 0:
  651.         {
  652.             choiceDelete(data);
  653.             break;
  654.         }
  655.         case 1:
  656.         case 2:
  657.         {
  658.             input(data, choice == 2);
  659.             break;
  660.         }
  661.         case 8:
  662.         {
  663.             printf("\n");
  664.             return;
  665.         }
  666.         default:
  667.         {
  668.             printf("\n Данной функции в программе нет\n");
  669.             break;
  670.         }
  671.         }
  672.     }
  673. }
  674.  
  675. int main()
  676. {
  677.     setlocale(LC_ALL, "");
  678.  
  679.     int choice = 0;
  680.     Data data;
  681.     while (true)
  682.     {
  683.         printf("0 - Ввод данных\n");
  684.         printf("1 - Удаление данных\n");
  685.         printf("2 - Вывод данных\n");
  686.         printf("3 - Сортировка данных\n");
  687.  
  688.         printf("8 - выйти\n");
  689.         scanf_s("%d", &choice);
  690.         switch (choice)
  691.         {
  692.         case 0:
  693.         {
  694.             menuInputData(data);
  695.             break;
  696.         }
  697.         case 1:
  698.         {
  699.             menuDeleteData(data);
  700.             break;
  701.         }
  702.         case 2:
  703.         {
  704.             menuOutputData(data);
  705.             break;
  706.         }
  707.         case 3:
  708.         {
  709.             menuSortData(data);
  710.             break;
  711.         }
  712.         case 8:
  713.         {
  714.             printf("\nдля завершения программы нажмите Enter...\n");
  715.             getchar();
  716.             deleteData(data);
  717.             _CrtDumpMemoryLeaks();
  718.             return 0;
  719.         }
  720.         default:
  721.         {
  722.             printf("\n данной функции в программе нет\n");
  723.             break;
  724.         }
  725.         }
  726.     }
  727. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement