Advertisement
oshige_san

Untitled

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