Advertisement
0_liprikon_0

Лабораторная работа №4

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