0_liprikon_0

Laba ispravlenie

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