Advertisement
oshige_san

Untitled

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