Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRTDBG_MAP_ALLOC
- #include <crtdbg.h>
- #include <memory.h>
- #include <stdio.h>
- #include <clocale>
- #include <cstdlib>
- #include <string>
- #include <conio.h>
- #include <windows.h>
- //Из 5 лабы
- void CopyString(char*& tmp, char*& String, int lenght, bool Creating)
- {
- if (Creating)
- {
- tmp = new char[lenght];
- }
- for (int index = 0; index < lenght; index++)
- {
- tmp[index] = String[index];
- }
- }
- void PushString(int& sizeString, char*& String, char last)
- {
- char* tmpStr = new char[sizeString + 1];
- CopyString(tmpStr, String, sizeString, false);
- delete[] String;
- String = tmpStr;
- sizeString++;
- String[sizeString - 1] = last;
- }
- void PopString(int& sizeString, char*& String)
- {
- if (sizeString > 0)
- {
- sizeString--;
- char* tmpStr;
- CopyString(tmpStr, String, sizeString, true);
- delete[] String;
- String = tmpStr;
- }
- }
- void EnterString(int& sizeString, char*& String)
- {
- char buf = 0; //Введенный символ (ввод до enter)
- while (true)
- {
- buf = _getch();
- switch (buf)
- {
- case 13:
- {
- PushString(sizeString, String, '\0');
- printf("\n");
- return;
- }
- case 8:
- {
- if (sizeString > 0)//Чтобы не стереть фразу (до) на той же строке, где и ввод
- {
- printf("\b");
- printf(" ");
- printf("\b");
- }
- PopString(sizeString, String);
- break;
- }
- default:
- {
- PushString(sizeString, String, buf);
- printf("%c", buf); // Так как нет эхо
- break;
- }
- }
- }
- }
- void EnterFileString(FILE* inputFile, int& sizeString, char*& String)
- {
- char buf = 0; //Введенный символ (ввод до enter)
- while (true)
- {
- buf = fgetc(inputFile);
- switch (buf)
- {
- case EOF:
- case ' ':
- case 10:
- {
- if ((buf == 10) && (sizeString == 0))
- {
- continue; //Лишние enter
- }
- PushString(sizeString, String, '\0');
- return;
- }
- default:
- {
- PushString(sizeString, String, buf);
- break;
- }
- }
- }
- }
- void PushVector(int& sizeVector, int*& Vector, int num)
- {
- int* tmp = new int[sizeVector + 1];
- for (int index = 0; index < sizeVector; index++)
- {
- tmp[index] = Vector[index];
- }
- delete[] Vector;
- Vector = tmp;
- sizeVector++;
- Vector[sizeVector - 1] = num;
- }
- //Здесь заканчиваются функции из 5 лабы
- //Функция для ввода значения, с проверкой принадлежности заданному диапазону
- //const char*, так как заранее заданная строка
- int correctScanf(int min, int max, const char* text)
- {
- int ret = 0;
- while (true)
- {
- printf("%s: ", text);
- scanf_s("%d", &ret);
- if (ret < min)
- {
- printf("\nВведённые данные слишком малы\n");
- continue; // начать с начала цикла (заново вводим)
- }
- else if (ret > max)
- {
- printf("\nВведённые данные слишком большие\n");
- continue; // начать с начала цикла (заново вводим)
- }
- break;
- }
- return ret;
- }
- int correctFileScanf(FILE* inputFile, int min, int max)
- {
- int ret;
- fscanf_s(inputFile, "%d", &ret);
- if (ret < min) return min;
- if (ret > max) return max;
- return ret;
- }
- struct Auto
- {
- char* brand = nullptr;//марка
- int sizeBrand = 0;// Размер строки, куда вводится название марки
- int date = 0;//дата выпуска
- int volume = 0;//объем двигателя
- int mileage = 0;//пробег
- //+ есть поле сумма налога, которое вычисляется при необходимости
- };
- struct Data
- {
- Auto* cars = nullptr;
- int size = 0;
- };
- //Вычисляемое поле, налог на транспортное средство
- //[0;100] -> 7 | (100;250] -> 14 | (250;..) -> 30
- //Я написала формулы не сокращая, чтобы было понятно, откуда взялись числа
- int getTax(int volume)
- {
- int res = 0;
- if (volume <= 100)
- res = volume * 7;
- else if (volume <= 250)
- res = volume * 14;
- else
- res = 30 * volume;
- return res;
- }
- bool isEqual(Auto left, Auto right)
- {
- if (strcmp(left.brand, right.brand) != 0) return false;
- if (left.date != right.date) return false;
- if (left.mileage != right.mileage) return false;
- if (left.volume != right.volume) return false;
- }
- bool comparisonAuto(Auto left, Auto right, int field)
- {
- switch (field)
- {
- case 1:
- if (left.date < right.date) return false;
- break;
- case 2:
- if (left.volume < right.volume) return false;
- break;
- case 3:
- if (left.mileage < right.mileage) return false;
- break;
- case 4:
- //Можно было бы и отсортировать по объему двигателя, так как чем он больше, тем больше и налог
- //Функция налога строго возрастает
- if (getTax(left.volume) < getTax(right.volume)) return false;
- break;
- default: // По умолчанию будет сортировка по марке
- if (strcmp(left.brand, right.brand) == -1) return false;
- break;
- }
- return true;
- }
- void CopyData(Data& buf, Data data, bool Creating)
- {
- if (Creating)
- {
- buf.cars = new Auto[data.size];
- buf.size = data.size;
- }
- for (int index = 0; index < data.size; ++index)
- {
- buf.cars[index] = data.cars[index];
- CopyString(buf.cars[index].brand, data.cars[index].brand, data.cars[index].sizeBrand, true);
- }
- }
- void deleteAuto(Auto& cars)
- {
- delete[] cars.brand;
- cars.brand = nullptr;
- cars.sizeBrand = 0;
- cars.date = 0;
- cars.mileage = 0;
- cars.volume = 0;
- }
- void deleteData(Data& data)
- {
- for (int i = 0; i < data.size; ++i)
- {
- deleteAuto(data.cars[i]);
- }
- delete[] data.cars;
- data.cars = nullptr;
- data.size = 0;
- }
- void deleteAllPosition(Data& data, int sizeVector, int* Vector)
- {
- if (sizeVector == data.size)//Удаляем всё
- {
- deleteData(data);
- return;
- }
- if (sizeVector == 0)
- {
- return; //Не нашли, что удалять
- }
- Data buf;
- buf.size = data.size - sizeVector;
- buf.cars = new Auto[buf.size];
- int j = 0;
- int l = 0;
- for (int i = 0; i < data.size; ++i)
- {
- if (i != Vector[j])
- {
- buf.cars[l] = data.cars[i];
- CopyString(buf.cars[l].brand, data.cars[i].brand, data.cars[i].sizeBrand, true);
- ++l;
- }
- else
- {
- ++j;
- }
- }
- deleteData(data);
- data = buf;
- }
- Auto inputOne(FILE* inputFile) //Если FILE* равен nullptr, будем считать, что работаем с консолью
- {
- Auto ret;
- if (inputFile != nullptr)
- {
- EnterFileString(inputFile, ret.sizeBrand, ret.brand);
- ret.date = correctFileScanf(inputFile, 1800, 2019);
- ret.volume = correctFileScanf(inputFile, 1, 10000);
- ret.mileage = correctFileScanf(inputFile, 0, 10000000);
- }
- else
- {
- printf("\nВведите название марки: ");
- EnterString(ret.sizeBrand, ret.brand);
- ret.date = correctScanf(1800, 2019, "Введите дату выпуска машины: ");
- ret.volume = correctScanf(1, 10000, "Введите объем двигателя машины: ");
- ret.mileage = correctScanf(0, 10000000, "Введите пробег машины: ");
- }
- return ret;
- }
- void BubbleSort(Data& data, int choice)//Сортировка пузырьком
- {
- Auto buf;
- int i = 0;
- int j = 0;
- for (i = 0; i < data.size; ++i)
- {
- for (j = 0; j < data.size - 1 - i; ++j) //До конца нет смысла доходить, так как 'пузырьки' всплывают
- {
- if (comparisonAuto(data.cars[j], data.cars[j + 1], choice))
- {
- buf = data.cars[j];
- data.cars[j] = data.cars[j + 1];
- data.cars[j + 1] = buf;
- }
- }
- }
- }
- void outData(Data data)
- {
- for (int i = 0; i < data.size; ++i)
- {
- printf("%d-я машина\n", i + 1);
- printf("Марка машины: %s\n", data.cars[i].brand);
- printf("Дата выпуска: %d\n", data.cars[i].date);
- printf("Объём двигателя: %d\n", data.cars[i].volume);
- printf("Пробег: %d\n", data.cars[i].mileage);
- printf("Налог: %d\n\n", getTax(data.cars[i].volume));
- }
- }
- void outFileData(FILE* outputFile, Data data)
- {
- fprintf(outputFile, "%d\n", data.size);
- for (int i = 0; i < data.size; ++i)
- {
- fprintf(outputFile, "%s\n", data.cars[i].brand);
- fprintf(outputFile, "%d\n", data.cars[i].date);
- fprintf(outputFile, "%d\n", data.cars[i].volume);
- fprintf(outputFile, "%d\n", data.cars[i].mileage);
- }
- }
- void output(Data& data, int choiceSort, bool withFile)
- {
- FILE* outputFile = nullptr;
- if (choiceSort >= 0)//Есть сортировка
- {
- BubbleSort(data, choiceSort);
- }
- if (withFile)
- {
- fopen_s(&outputFile, "in.txt", "w");
- if (outputFile == NULL)
- {
- fprintf(stderr, "Не удалось открыть файл");
- }
- outFileData(outputFile, data);
- fclose(outputFile);
- }
- else
- {
- outData(data);
- }
- }
- void input(Data& data, bool withFile)
- {
- int i = 0;
- int j = 0; // Чтобы записывать, начиная с середины (то есть дополнять массив)
- int num = 0;
- FILE* inputFile = nullptr;
- if (withFile)
- {
- fopen_s(&inputFile, "in.txt", "r");
- if (inputFile == NULL)
- {
- printf("Файл не найден!\n");
- exit(0);
- }
- if (getc(inputFile) == EOF)
- {
- printf("Файл пуст!");
- exit(0);
- }
- fclose(inputFile);
- FILE* inputFile = nullptr;
- fopen_s(&inputFile, "in.txt", "r");
- num = correctFileScanf(inputFile, 0, 100000);
- }
- else
- {
- num = correctScanf(0, 100000, "Введите количество машин");
- }
- j = data.size;
- Data buf;
- CopyData(buf, data, true);
- deleteData(data);
- data.size = buf.size + num;
- if (data.size > 0)
- {
- data.cars = new Auto[data.size];
- }
- CopyData(data, buf, false);
- deleteData(buf);
- for (i = 0; i < num; i++, j++)
- {
- data.cars[j] = inputOne(inputFile);
- }
- }
- void deleteData(Data& data, int choice)
- {
- if (data.size == 0)
- {
- printf("\n------- Массив пуст, удалять нечего -----\n");
- return;
- }
- int* whoIsDelete = nullptr;
- int num = 0;
- int i = 0;
- int amount = 0;
- Auto buf; //Для считывания, а потом поиска на соответствие
- switch (choice)
- {
- case 0:
- {
- //Приводим к общему типу (якобы могло быть несколько удаляемых объектов
- whoIsDelete = new int[1];
- num = correctScanf(1, data.size, "Введите порядковый номер");
- whoIsDelete[0] = num - 1;
- amount = 1;
- break;
- }
- case 1:
- {
- printf("\n Введите название марки :");
- char* brand = nullptr;
- int sizeBrand = 0;
- EnterString(sizeBrand, brand);
- for (i = 0; i < data.size; ++i)
- {
- if (strcmp(brand, data.cars[i].brand) == 0)
- {
- PushVector(amount, whoIsDelete, i);
- }
- }
- delete[] brand;
- break;
- }
- case 2:
- {
- buf = inputOne(nullptr); // Всегда считываем с консоли
- for (i = 0; i < data.size; ++i)
- {
- if (isEqual(buf, data.cars[i]))
- {
- PushVector(amount, whoIsDelete, i);
- }
- }
- deleteAuto(buf);
- break;
- }
- }
- deleteAllPosition(data, amount, whoIsDelete);
- delete[] whoIsDelete;
- }
- void choiceDelete(Data& data)
- {
- printf("\n Если хотите отменить, введите \"no\"\n если хотите продолжить, можете ввести любую строку :");
- char* cancel = nullptr;
- int size = 0;
- EnterString(size, cancel);
- if (strcmp(cancel, "no") != 0)
- {
- deleteData(data);
- }
- delete[] cancel;
- }
- void menuSortData(Data& data)
- {
- int choice = 0;
- while (true)
- {
- printf("\n------- Подменю сортировки данных -----\n");
- printf("0 - Удалить всё\n");
- printf("1 - Отсортировать по названию марки\n");
- printf("2 - Отсортировать по году выпуску\n");
- printf("3 - Отсортировать по объёму двигателя\n");
- printf("4 - Отсортировать по пробегу\n");
- printf("5 - Отсортировать по сумме налога на т.с.\n");
- printf("8 - выйти из меню ввода данных\n");
- scanf_s("%d", &choice);
- switch (choice)
- {
- case 0:
- {
- choiceDelete(data);
- break;
- }
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- {
- BubbleSort(data, choice - 1);
- break;
- }
- case 8:
- {
- return;
- }
- default:
- {
- printf("\n данной функции в программе нет\n");
- break;
- }
- }
- }
- }
- void menuDeleteData(Data& data)
- {
- int choice = 0;
- while (true)
- {
- printf("\n------- Подменю удаления данных -----\n");
- printf("0 - Удалить всё\n");
- printf("1 - удалить сведения о машине по порядковому номеру в массиве (от единицы)\n");
- printf("2 - удалить сведения всех машин указанной марки\n");
- printf("3 - удалить сведения о машине по совпадению всех данных\n");
- printf("8 - выйти из меню ввода данных\n");
- scanf_s("%d", &choice);
- switch (choice)
- {
- case 0:
- {
- choiceDelete(data);
- break;
- }
- case 1:
- case 2:
- case 3:
- {
- deleteData(data, choice - 1);
- break;
- }
- case 8:
- {
- return;
- }
- default:
- {
- printf("\n данной функции в программе нет\n");
- break;
- }
- }
- }
- }
- void menuOutputData(Data& data)
- {
- int choice = 0;
- while (true)
- {
- printf("\n------- Подменю вывода данных -----\n");
- printf("0 - Удалить всё\n");
- printf("1 - вывести данные на консоль (без сортировки)\n");
- printf("2 - Отсортировать по названию марки (консоль)\n");
- printf("3 - Отсортировать по году выпуску (консоль)\n");
- printf("4 - Отсортировать по объёму двигателя (консоль)\n");
- printf("5 - Отсортировать по пробегу (консоль)\n");
- printf("6 - Отсортировать по сумме налога на т.с. (консоль)\n");
- printf("\n------------------\n");
- printf("7 - вывести данные в файл (без сортировки)\n");
- printf("8 - Отсортировать по названию марки (в файл)\n");
- printf("9 - Отсортировать по году выпуску (в файл)\n");
- printf("10 - Отсортировать по объёму двигателя (в файл)\n");
- printf("11 - Отсортировать по пробегу (в файл)\n");
- printf("12 - Отсортировать по сумме налога на т.с. (в файл)\n");
- printf("13 - выйти из меню вывода данных\n");
- scanf_s("%d", &choice);
- if (choice == 0)
- {
- choiceDelete(data);
- }
- else
- {
- if (choice <= 6)
- {
- output(data, choice - 2, false);
- }
- else
- {
- if (choice <= 12)
- {
- output(data, choice - 8, true);
- }
- else
- {
- if (choice == 13)
- {
- return;
- }
- printf("\n данной функции в программе нет\n");
- }
- }
- }
- }
- }
- void menuInputData(Data& data)
- {
- int choice = 0;
- while (true)
- {
- printf("\n------- Подменю ввода данных -----\n");
- printf("0 - Удалить всё\n");
- printf("1 - добавить данные с консоли в конец\n");
- printf("2 - добавить данные с указанного файла в конец\n");
- printf("8 - выйти из меню ввода данных\n");
- scanf_s("%d", &choice);
- switch (choice)
- {
- case 0:
- {
- choiceDelete(data);
- break;
- }
- case 1:
- case 2:
- {
- input(data, choice == 2);
- break;
- }
- case 8:
- {
- printf("\n");
- return;
- }
- default:
- {
- printf("\n Данной функции в программе нет\n");
- break;
- }
- }
- }
- }
- int main()
- {
- setlocale(LC_ALL, "");
- int choice = 0;
- Data data;
- while (true)
- {
- printf("0 - Ввод данных\n");
- printf("1 - Удаление данных\n");
- printf("2 - Вывод данных\n");
- printf("3 - Сортировка данных\n");
- printf("8 - выйти\n");
- scanf_s("%d", &choice);
- switch (choice)
- {
- case 0:
- {
- menuInputData(data);
- break;
- }
- case 1:
- {
- menuDeleteData(data);
- break;
- }
- case 2:
- {
- menuOutputData(data);
- break;
- }
- case 3:
- {
- menuSortData(data);
- break;
- }
- case 8:
- {
- printf("\nдля завершения программы нажмите Enter...\n");
- getchar();
- deleteData(data);
- _CrtDumpMemoryLeaks();
- return 0;
- }
- default:
- {
- printf("\n данной функции в программе нет\n");
- break;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement