oshige_san

Untitled

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