oshige_san

Untitled

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