Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include <iostream>
- #include <conio.h>
- #include <sstream>
- #include <Windows.h>
- #include <iomanip>
- #include <fstream>
- using namespace std;
- typedef int ElemType;
- #define MemoryAllocationBad -1
- #define MemoryAllocationGood -2
- struct matrix {
- int row;
- int col;
- };
- struct InvalidElement {
- int row;
- int col;
- int pos;
- };
- enum Error {
- NotFail,
- ErrorOpenFile,
- ErrorFileEOF,
- ErrorRectangle,
- ErrorMemoryAllocation,
- ErrorProcessingMatr,
- ErrorInvalidElement
- };
- union ErrorInfo {
- int OpenFile;
- int Rectangle;
- int ProcessingMatr;
- int MemoryAllocation;
- InvalidElement Element;
- };
- void ErrorCase() {
- cout << "Нажмите любую клавишу для продолжения." << endl;
- _getch();
- system("cls");
- }
- void DeleteMatr(int row, ElemType** matr) {
- if (!matr)
- return;
- for (int i = 0; i < row; i++)
- delete[] matr[i];
- delete[] matr;
- matr = nullptr;
- }
- ElemType**& MemoryAllocation(const matrix& Matr, ElemType**& matr, ErrorInfo* EInfo = nullptr) {
- int i = MemoryAllocationBad;
- matr = nullptr;
- try
- {
- matr = new ElemType*[Matr.row];
- for (i = 0; i < Matr.row; i++)
- matr[i] = new ElemType[Matr.col];
- }
- catch (...)
- {
- if(matr != nullptr)
- DeleteMatr(i, matr);
- if (EInfo!=nullptr)
- EInfo->MemoryAllocation = i;
- }
- return matr;
- }
- Error LoadMatr(const string& FileName, matrix& DimensionMatr, ElemType**& matr, ErrorInfo* EInfo = nullptr) {
- ifstream fin;
- ElemType symbol;
- int details = 0, AbsSymbolPos;
- char FlowState = 0, state;
- bool CompleteCheck = true;
- DimensionMatr.col = 0;
- DimensionMatr.row = 0;
- matr = nullptr;
- fin.open(FileName);
- if (!fin.is_open()) {
- if (EInfo) {
- EInfo->OpenFile = errno;
- }
- return ErrorOpenFile;
- }
- fin >> ws;
- if (fin.eof()) {
- fin.close();
- return ErrorFileEOF;
- }
- while (CompleteCheck) {
- if (EInfo)
- AbsSymbolPos = fin.tellg();
- fin >> symbol;
- if (fin.fail() || ((state = fin.peek()) != ' ' && state != '\t' && state != '\n' && state != EOF)) {
- fin.close();
- if (EInfo) {
- EInfo->Element.row = DimensionMatr.row;
- EInfo->Element.col = DimensionMatr.col;
- EInfo->Element.pos = AbsSymbolPos;
- }
- DimensionMatr.col = 0;
- DimensionMatr.row = 0;
- return ErrorInvalidElement;
- }
- DimensionMatr.col++;
- while (FlowState != EOF) {
- FlowState = fin.get();
- switch (FlowState) {
- case ' ': case '\t':
- break;
- case EOF:
- CompleteCheck = false;
- case '\n':
- if (DimensionMatr.col) {
- if (details != DimensionMatr.col * (DimensionMatr.row)) {
- fin.close();
- if (EInfo)
- EInfo->Rectangle = DimensionMatr.row;
- DimensionMatr.col = 0;
- DimensionMatr.row = 0;
- return ErrorRectangle;
- }
- DimensionMatr.row++;
- details += DimensionMatr.col;
- DimensionMatr.col = 0;
- }
- break;
- default:
- //fin.seekg(-1, ios::cur);
- //fin.seekg(fin.tellg()-1);
- fin.unget();
- FlowState = EOF;
- }
- }
- FlowState = 0;
- }
- DimensionMatr.col = details / DimensionMatr.row;
- //int ErrorMA;
- matr = MemoryAllocation(DimensionMatr, matr);
- if (!matr) {
- fin.close();
- //if (EInfo != NULL)
- //EInfo->MemoryAllocation = ErrorMA;
- return ErrorMemoryAllocation;
- }
- fin.clear();
- fin.seekg(0);
- for (int i = 0; i < DimensionMatr.row; i++) {
- for (int j = 0; j < DimensionMatr.col; j++)
- fin >> matr[i][j];
- }
- fin.close();
- return NotFail;
- }
- void MatrProcessing(const matrix& DimensionMatr, ElemType** matr) {
- int MinSumA = 0, SumA;
- for (int i = 0; i < DimensionMatr.row; i++)
- MinSumA += matr[i][0];
- for (int i = 1; i < DimensionMatr.col; i++) {
- SumA = 0;
- for (int j = 0; j < DimensionMatr.row; j++)
- SumA += matr[j][i];
- if (MinSumA > SumA)
- MinSumA = SumA;
- }
- for (int i = 0; i < DimensionMatr.row; i++)
- for (int j = 0; j < DimensionMatr.col; j++)
- matr[i][j] -= MinSumA;
- }
- bool CopyMatr(const matrix& Matr, ElemType** matr, ElemType**& DuplicateMatr, ErrorInfo* EInfo = nullptr) {
- //int ErrorMA;
- matr = MemoryAllocation(Matr, DuplicateMatr);
- if (!matr) {
- //if (EInfo != nullptr)
- //EInfo->MemoryAllocation = ErrorMA;
- return false;
- }
- for (int i = 0; i < Matr.row; i++)
- for (int j = 0; j < Matr.col; j++)
- DuplicateMatr[i][j] = matr[i][j];
- return true;
- }
- string OutMatr(matrix& Matr, ElemType**& matr, int precision = 2, int width = 7, ios_base::fmtflags flag = ios_base::dec) {
- stringstream sMatr;
- if (flag & ios::basefield)
- sMatr.setf(flag, ios_base::basefield);
- if (flag & ios::floatfield)
- sMatr.setf(flag, ios_base::floatfield);
- if (flag & ios::adjustfield)
- sMatr.setf(flag, ios_base::adjustfield);
- sMatr.setf(flag);
- sMatr << fixed << setprecision(precision);
- for (int i = 0; i < Matr.row; i++) {
- for (int j = 0; j < Matr.col; j++)
- sMatr << left << setw(width) << matr[i][j];
- sMatr << "\r\n";
- }
- return string(sMatr.str());
- }
- int main()
- {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- int mistake;
- ErrorInfo EInfo;
- string FileName, MatrStr;
- ElemType** Matr;
- matrix DimensionMatr;
- while (true) {
- system("cls");
- cout << "Введите название файла или * для прекращения работы программы." << endl;
- cin.ignore(cin.rdbuf()->in_avail());
- getline(cin, FileName);
- if (FileName == "*")
- return 0;
- mistake = LoadMatr(FileName, DimensionMatr, Matr, &EInfo);
- if (mistake != NotFail) {
- switch (mistake) {
- case ErrorOpenFile:
- cout << "Не удалось открыть файл \"" << FileName << "\". Код системной ошибки: " << EInfo.OpenFile << endl;
- ErrorCase();
- continue;
- case ErrorFileEOF:
- cout << "Файл не содержит данных." << endl;
- break;
- case ErrorInvalidElement:
- cout << "Некорректный элемент в " << EInfo.Element.row + 1 << " строке, "
- << EInfo.Element.col + 1 << " столбце, под №" << EInfo.Element.pos << endl;
- break;
- case ErrorRectangle:
- cout << "Матрица не прямоугольная, начиная с " << EInfo.Rectangle + 1 << " строки." << endl;
- break;
- case ErrorMemoryAllocation:
- if (ErrorMemoryAllocation == MemoryAllocationBad)
- cout << "Не удалось выделить память под массив указателей." << endl;
- else
- cout << "Не удалось выделить память под " << EInfo.MemoryAllocation << " строку." << endl;
- break;
- }
- cout << "Нажмите любую клавишу для продолжения." << endl;
- _getch();
- system("cls");
- continue;
- }
- cout << "Изначальная матрица:" << endl;
- cout << OutMatr(DimensionMatr, Matr);
- ElemType** DuplicateMatr;
- mistake = CopyMatr(DimensionMatr, Matr, DuplicateMatr, &EInfo);
- if (!mistake) {
- DeleteMatr(DimensionMatr.row, Matr);
- if (EInfo.MemoryAllocation == MemoryAllocationBad)
- cout << "Не удалось выделить память под массив указателей." << endl;
- else
- cout << "Не удалось выделить память " << EInfo.MemoryAllocation << " строку." << endl;
- ErrorCase();
- continue;
- }
- MatrProcessing(DimensionMatr, DuplicateMatr);
- cout << endl << "Обработанная матрица:" << endl;
- cout << OutMatr(DimensionMatr, DuplicateMatr);
- DeleteMatr(DimensionMatr.row, Matr);
- DeleteMatr(DimensionMatr.row, DuplicateMatr);
- _getch();
- system("cls");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement