Advertisement
oshige_san

Untitled

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