0_liprikon_0

Лаба 4

Sep 22nd, 2021
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.08 KB | None | 0 0
  1. #include <iostream> //объявляет объекты, управляющие чтением из стандартных потоков и записью в них
  2. #include <iomanip> //определение нужного числа манипуляторов, каждый из которых принимает один аргумент
  3. #include <Windows.h> //функции WinAPI, константы, типы, прототипы и др.
  4. #include <conio.h> //объявляет несколько библиотечных функций для работы с «консольным вводом и выводом» программы (_getch())
  5. #include <fstream> //определяет несколько классов, поддерживающих операции iostreams для последовательностей, хранящихся во внешних файлах
  6. #include <sstream> //определяет несколько шаблонов классов, поддерживающих операции iostream для последовательностей, хранящихся в выделенном объекте массива
  7. #include <cerrno> //имена, объявленные с помощью внешней компоновки в заголовке стандартной библиотеки C, объявляются в std пространстве имен
  8. #include <string> //методы и переменные для организации работы со строками
  9.  
  10. using namespace std; //std-пространство имён, содержащее все типы и функции стандартной библиотеки с++
  11.  
  12. #define AllocGood -2 //Выделяет блок памяти указанного размера из подраспределителя кэширования среды параллелизма
  13. #define AllocBad -1
  14.  
  15. // внутренний код ошибки
  16.  
  17. //Объявляет перечисление в области видимости пространства имен, которое является определяемым пользователем типом,
  18. //состоящим из ряда именованных констант, называемых перечислителями.
  19. enum Outcomes {
  20.     All_Good, //Все хорошо
  21.     Error_Open,//Ошибка открытия файла
  22.     File_Empty,//Пустой файл
  23.     Error_Elements,//Некорректный элемент
  24.     Not_Rectangular,//Непрямоугольная
  25.     Error_Of_Memory//Ошибка выделения памяти
  26. };
  27.  
  28. //объединение
  29.  
  30.  
  31. union MyUnion { // все члены совместно используют одно и то же расположение в памяти
  32.  
  33.     struct ErrorMatrix { //ошибки в матрице
  34.  
  35.         int row; //строка
  36.         int column; //столбец
  37.         int pos; //позиция
  38.  
  39.     } ErrElem; //имя ошибки
  40.  
  41.     int ErrRectRow;
  42.  
  43.     int ErrAlloc; //ошибка памяти
  44.  
  45.     int ErrOpen; //ошибка открытия
  46. };// NoArg;// = { -1 };
  47.  
  48. //проверка на корректность, прямоугольность, пустоту
  49. Outcomes CheckingMatrix(ifstream& fin, int& row_counter, int& column_counter, MyUnion* VariosError = NULL/*MyUnion &VariosError = NoArg*/) {
  50.     int pos, quantity_of_elements_in_the_other_row = 0;
  51.     //if (&VariosError == &NoArg) // if (VariosError.ErrOpen != -1)
  52.     column_counter = 0;
  53.     row_counter = 0;
  54.     while (true) {
  55.  
  56.         char c = fin.get();
  57.         int var;
  58.         switch (c) {
  59.  
  60.         case ' ': case '\t':
  61.             continue;
  62.         case EOF:
  63.             if (quantity_of_elements_in_the_other_row == 0)
  64.                 break;
  65.         case '\n':
  66.             if (quantity_of_elements_in_the_other_row == 0)
  67.                 continue;
  68.             if (column_counter == 0)
  69.                 column_counter = quantity_of_elements_in_the_other_row;
  70.             else if (column_counter != quantity_of_elements_in_the_other_row) {
  71.                 if (VariosError != NULL)
  72.                     VariosError->ErrRectRow = row_counter;
  73.                 row_counter = 0;
  74.                 column_counter = 0;
  75.                 return Outcomes::Not_Rectangular;
  76.             }
  77.             row_counter++;
  78.             quantity_of_elements_in_the_other_row = 0;
  79.             continue;
  80.         default:
  81.             fin.unget();
  82.             if (VariosError != NULL)
  83.                 pos = fin.tellg();
  84.             fin >> var;
  85.             if (fin.fail() || ((c = fin.peek()) != ' ' && c != '\t' && c != '\n' && c != EOF)) {
  86.                 if (VariosError != NULL) {
  87.                     VariosError->ErrElem.row = row_counter;
  88.                     VariosError->ErrElem.column = quantity_of_elements_in_the_other_row;
  89.                     VariosError->ErrElem.pos = pos;
  90.                 }
  91.                 row_counter = 0;
  92.                 column_counter = 0;
  93.                 return Outcomes::Error_Elements;
  94.             }
  95.             quantity_of_elements_in_the_other_row++;
  96.             continue;
  97.         }
  98.         if (column_counter == 0) {
  99.             row_counter = 0;
  100.             return Outcomes::File_Empty;
  101.         }
  102.         return Outcomes::All_Good;
  103.     }
  104. }
  105.  
  106. //освобождение памяти
  107. void DeletingMatrix(int**& matr, int row_counter) {
  108.     for (int k = 0; k < row_counter; k++)
  109.         delete[]matr[k];
  110.     delete[]matr;
  111.     matr = NULL;
  112. }
  113.  
  114. //выделение памяти
  115. int** AllocatingMatrix(int row_counter, int column_counter, int& i) {
  116.  
  117.     int** matr = NULL;
  118.     i = AllocBad;
  119.     try {
  120.         matr = new int* [row_counter];
  121.         for (i = 0; i < row_counter; i++)
  122.             matr[i] = new int[column_counter];
  123.     }
  124.     catch (...) {
  125.         if (matr != NULL)
  126.             DeletingMatrix(matr, i);
  127.         return NULL;
  128.     }
  129.     i = AllocGood;
  130.     return matr;
  131. }
  132.  
  133. //чтение матрицы
  134. int** ReadingMatrix(ifstream& fin, int** matr, int row_counter, int column_counter) {
  135.     for (int i = 0; i < row_counter; i++)
  136.         for (int j = 0; j < column_counter; j++)
  137.             fin >> *(*(matr + i) + j);
  138.     return matr;
  139. }
  140.  
  141. //вывод матрицы в консоль
  142. string MatrixToStr(int** matr, int row_counter, int column_counter, int number = 5) {
  143.  
  144.     ostringstream ss;
  145.     for (int i = 0; i < row_counter; i++) {
  146.         for (int j = 0; j < column_counter; j++)
  147.             ss << setw(number) << matr[i][j];
  148.         ss << endl;
  149.     }
  150.     return ss.str();
  151. }
  152.  
  153. //обработка матрицы
  154. int** ProcessingMatrix(int** matr, int row_counter, int column_counter, int a, int b, int c, int d) {
  155.  
  156.     int sum = 0;
  157.     if (a == c)
  158.         for (; b < d + 1; b++)
  159.             sum += matr[a][b];
  160.     else {
  161.         for (; b < column_counter; b++)
  162.             sum += matr[a][b];
  163.         for (int e = a + 1; e < c; e++)
  164.             for (int r = 0; r < column_counter; r++)
  165.                 sum += matr[e][r];
  166.         for (int w = 0; w < d + 1; w++)
  167.             sum += matr[c][w];
  168.     }
  169.     for (int j = 0; j < column_counter; j++)
  170.         matr[0][j] = sum;
  171.  
  172.     return matr;
  173. }
  174.  
  175. //копирование элементов
  176. int** Copy(int** matr, int** copy_matr, int row_counter, int column_counter) {
  177.     for (int i = 0; i < row_counter; i++)
  178.         for (int j = 0; j < column_counter; j++)
  179.             copy_matr[i][j] = matr[i][j];
  180.     return copy_matr;
  181. }
  182.  
  183. //Создание копии матрицы
  184. int** CopyingMatrix(int** matr, int row_counter, int column_counter, int& i) {
  185.  
  186.     int** copy_matr = AllocatingMatrix(row_counter, column_counter, i);
  187.  
  188.     if (copy_matr == NULL)
  189.         return NULL;
  190.  
  191.     return Copy(matr, copy_matr, row_counter, column_counter);
  192. }
  193.  
  194. //загрузка матрицы
  195. Outcomes LoadingMatrix(const string& file, int**& matr, int& row_counter, int& column_counter, MyUnion* VariosError = NULL) {
  196.  
  197.     Outcomes result;
  198.  
  199.     ifstream fin;
  200.     fin.open(file);
  201.     if (!fin) {
  202.         if (VariosError != NULL)
  203.             VariosError->ErrOpen = errno;
  204.         matr = NULL;
  205.         row_counter = 0;
  206.         column_counter = 0;
  207.         return Outcomes::Error_Open;
  208.     }
  209.  
  210.     result = CheckingMatrix(fin, row_counter, column_counter, VariosError);
  211.     if (result != Outcomes::All_Good) {
  212.         fin.close();
  213.         matr = NULL;
  214.         return result;
  215.     }
  216.     int i;
  217.     matr = AllocatingMatrix(row_counter, column_counter, i);
  218.     if (matr == NULL) {
  219.         fin.close();
  220.         if (VariosError != NULL)
  221.             VariosError->ErrAlloc = i;
  222.         row_counter = 0;
  223.         column_counter = 0;
  224.         return Outcomes::Error_Of_Memory;
  225.     }
  226.  
  227.     fin.clear();
  228.     fin.seekg(0);
  229.     ReadingMatrix(fin, matr, row_counter, column_counter);
  230.     fin.close();
  231.  
  232.     return Outcomes::All_Good;
  233. }
  234.  
  235. //главная
  236. int main() {
  237.  
  238.     SetConsoleCP(1251);
  239.     SetConsoleOutputCP(1251);
  240.  
  241.     for (;;) {
  242.  
  243.         cout << "Введите имя файла или \"*\" для завершения работы: ";
  244.         if (cin.peek() == '*' && cin.rdbuf()->in_avail() == 2)
  245.             return 0;
  246.  
  247.         MyUnion VariosError;
  248.  
  249.         int row_counter, column_counter;
  250.         Outcomes result;
  251.  
  252.         string file;
  253.         getline(cin, file);
  254.  
  255.         int** matr;
  256.  
  257.         if ((result = LoadingMatrix(file, matr, row_counter, column_counter, &VariosError)) != Outcomes::All_Good) {
  258.  
  259.             cout << "\nКод ошибки: " << result << endl;
  260.  
  261.             switch (result) {
  262.             case Error_Open:
  263.                 cout << "Системный код ошибки \"errno\": " << VariosError.ErrOpen << endl;
  264.                 break;
  265.             case File_Empty:
  266.                 cout << "\nФайл пуст.";
  267.                 break;
  268.             case Error_Elements: {
  269.                 ifstream fin(file); //открытие файла для чтения
  270.                 fin.seekg(VariosError.ErrElem.pos);
  271.                 string split;
  272.                 fin >> split; //считывание первой строки файла
  273.                 fin.close(); //закрытие файла
  274.                 cout << "\nОшибка в строке " << 1 + VariosError.ErrElem.row << " в столбце " << 1 + VariosError.ErrElem.column << '.';
  275.                 cout << "\nНекорректный элемент имеет последовательность: " << split;
  276.                 break;
  277.             }
  278.             case Not_Rectangular:
  279.                 cout << "\nМатрица не прямоугольна, начиная со строки " << 1 + VariosError.ErrRectRow << '.';
  280.                 break;
  281.             case Error_Of_Memory:
  282.                 if (VariosError.ErrAlloc == AllocBad) {
  283.                     cout << "\nОшибка выделения памяти под массив указателей для строк матрицы.\n";
  284.                     break;
  285.                 }
  286.                 else {
  287.                     cout << "\nОшибка выделения памяти под строки матрицы, начиная со строки " << VariosError.ErrAlloc + 1 << ".\n";
  288.                     break;
  289.                 }
  290.             }
  291.  
  292.             cout << "\nНажмите любую клавишу, чтобы продолжить...";
  293.             _getch();
  294.             system("cls");
  295.             continue;
  296.         }
  297.  
  298.         cout << "\n\nИсходная матрица: \n\n";
  299.         cout << MatrixToStr(matr, row_counter, column_counter);
  300.  
  301.         int i;
  302.         int** copy_matr = CopyingMatrix(matr, row_counter, column_counter, i); //указатель на указатель для копии двумерного массива
  303.         if (i == AllocBad) {
  304.             cout << "\nОшибка выделения памяти под массив указателей для строк матрицы.\n";
  305.             continue;
  306.         }
  307.         else if (i >= 0) {
  308.             cout << "\nОшибка выделения памяти под строки матрицы, начиная со строки " << i + 1 << ".\n";
  309.             continue;
  310.         }
  311.  
  312.         cout << "\n\nВведите границы диапазона строк и столбцов(для Х и Y).\n";
  313.  
  314.         int a = -1, b = -1, c = -1, d = -1, mas[4], sum = 0;
  315.  
  316.         for (int i = 0; i < 4;) {
  317.  
  318.             cin.ignore(cin.rdbuf()->in_avail());
  319.             if (cin.peek() == '*' && cin.rdbuf()->in_avail() == 2) {
  320.                 DeletingMatrix(matr, row_counter);
  321.                 return 0;
  322.             }
  323.             if (cin.peek() == '\n')
  324.                 continue;
  325.  
  326.             cin >> mas[i];
  327.  
  328.             if (cin.peek() != '\n') {
  329.                 cin.clear();
  330.                 cin.ignore(cin.rdbuf()->in_avail());
  331.                 cout << "Некорректный ввод значений для диапозона Х и Y. Повторите ввод.\n\n";
  332.                 continue;
  333.             }
  334.  
  335.             if (a == -1) {
  336.                 a = mas[i] - 1;
  337.                 if (a < 0 || a > row_counter - 1) {
  338.                     a = -1;
  339.                     cout << "Недопустимый ввод строки для значения Х. Повторите ввод.\n\n";
  340.                     continue;
  341.                 }
  342.             }
  343.             else if (a != -1 && b == -1) {
  344.                 b = mas[i] - 1;
  345.                 if (b < 0 || b > column_counter - 1) {
  346.                     b = -1;
  347.                     cout << "Недопустимый ввод столбика для значения Х. Повторите ввод.\n\n";
  348.                     continue;
  349.                 }
  350.             }
  351.             else if (a != -1 && b != -1 && c == -1) {
  352.                 c = mas[i] - 1;
  353.                 if (c > row_counter - 1 || c < 0 || c < a) {
  354.                     c = -1;
  355.                     cout << "Недопустимый ввод строки для значения Y. Повторите ввод.\n\n";
  356.                     continue;
  357.                 }
  358.             }
  359.             else if (a != -1 && b != -1 && c != -1) {
  360.                 d = mas[i] - 1;
  361.                 if (d > column_counter - 1 || d < 0 || (a == c && b > d)) {
  362.                     cout << "Недопустимый ввод столбика для значения Y. Повторите ввод.\n\n";
  363.                     continue;
  364.                 }
  365.             }
  366.             i++;
  367.         }
  368.  
  369.         ProcessingMatrix(matr, row_counter, column_counter, a, b, c, d);
  370.  
  371.         cout << "\n\nОбработанная матрица: \n\n";
  372.         cout << MatrixToStr(matr, row_counter, column_counter);
  373.  
  374.         //проверка на вывод копии(начальная) и обработанная(начальная обработанная)
  375.         /*      cout << "\n\n=============================\n\n";
  376.         cout << "First: \n";
  377.         cout << MatrixToStr(copy_matr, row_counter, column_counter);
  378.         cout << "Second: \n";
  379.         cout << MatrixToStr(matr, row_counter, column_counter);*/
  380.  
  381.         DeletingMatrix(matr, row_counter);
  382.         DeletingMatrix(copy_matr, row_counter);
  383.         return 0;
  384.     }
  385. }
Advertisement
Add Comment
Please, Sign In to add comment