Advertisement
oshige_san

Untitled

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