Advertisement
oshige_san

Untitled

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