Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Определить номер строки с минимальным количеством нулевых элементов и
- //сложить элементы этой строки с соответствующими элементами всех нечетных строк.
- #include <iostream>
- #include <iomanip>
- #include <Windows.h>
- #include <conio.h>
- #include <fstream>
- #include <sstream>
- #include <cerrno>
- #include <string>
- using namespace std;
- #define AllocGood -2
- #define AllocBad -1
- // внутренний код ошибки
- enum Outcomes {
- All_Good,
- Error_Open,
- File_Empty,
- Error_Elements,
- Not_Rectangular,
- Error_Of_Memory
- };
- typedef int elemtype;
- //ошибки в матрице
- union MyUnion {
- struct ErrorMatrix {
- int row;
- int column;
- int pos;
- } ErrElem;
- int ErrRectRow;
- int ErrAlloc;
- int ErrOpen;
- };
- //проверка на корректность, прямоугольность, пустоту
- Outcomes CheckingMatrix(ifstream& fin, int& row_counter, int& column_counter, MyUnion* VariosError = NULL) {
- int pos, quantity_of_elements_in_the_other_row = 0;
- column_counter = 0;
- row_counter = 0;
- while (true) {
- char c = fin.get();
- int var;
- switch (c) {
- case ' ': case '\t':
- continue;
- case EOF:
- if (quantity_of_elements_in_the_other_row == 0)
- break;
- case '\n':
- if (quantity_of_elements_in_the_other_row == 0)
- continue;
- if (column_counter == 0)
- column_counter = quantity_of_elements_in_the_other_row;
- else if (column_counter != quantity_of_elements_in_the_other_row) {
- if (VariosError != NULL)
- VariosError->ErrRectRow = row_counter;
- row_counter = 0;
- column_counter = 0;
- return Outcomes::Not_Rectangular;
- }
- row_counter++;
- quantity_of_elements_in_the_other_row = 0;
- continue;
- default:
- fin.unget();
- if (VariosError != NULL)
- pos = fin.tellg();
- fin >> var;
- if (fin.fail() || ((c = fin.peek()) != ' ' && c != '\t' && c != '\n' && c != EOF)) {
- if (VariosError != NULL) {
- VariosError->ErrElem.row = row_counter;
- VariosError->ErrElem.column = quantity_of_elements_in_the_other_row;
- VariosError->ErrElem.pos = pos;
- }
- row_counter = 0;
- column_counter = 0;
- return Outcomes::Error_Elements;
- }
- quantity_of_elements_in_the_other_row++;
- continue;
- }
- if (column_counter == 0) {
- row_counter = 0;
- return Outcomes::File_Empty;
- }
- return Outcomes::All_Good;
- }
- }
- //освобождение памяти
- void DeletingMatrix(elemtype**& matr, int row_counter) {
- for (int k = 0; k < row_counter; k++)
- delete[]matr[k];
- delete[]matr;
- matr = NULL;
- }
- //выделение памяти
- elemtype** AllocatingMatrix(int row_counter, int column_counter) {
- elemtype** matr = NULL;
- int j = AllocBad;
- try {
- matr = new elemtype * [row_counter];
- for (j = 0; j < row_counter; j++)
- matr[j] = new elemtype[column_counter];
- }
- catch (...) {
- if (matr != NULL)
- DeletingMatrix(matr, j);
- return NULL;
- }
- j = AllocGood;
- return matr;
- }
- //чтение матрицы
- elemtype** ReadingMatrix(ifstream& fin, elemtype** matr, int row_counter, int column_counter) {
- for (int i = 0; i < row_counter; i++)
- for (int j = 0; j < column_counter; j++)
- fin >> *(*(matr + i) + j);
- return matr;
- }
- //вывод матрицы в консоль
- string MatrixToStr(elemtype** matr, int row_counter, int column_counter, int number = 5, int t = 0, char z = ' ', ios::fmtflags format = 0) {
- ostringstream ss;
- if (format) {
- if (format & std::ios_base::floatfield)
- ss.setf(format, std::ios_base::floatfield);
- if (format & std::ios_base::adjustfield)
- ss.setf(format, std::ios_base::adjustfield);
- ss.setf(format);
- }
- for (int i = 0; i < row_counter; i++) {
- for (int j = 0; j < column_counter; j++)
- ss << setw(number) << setprecision(t) << setfill(z) << matr[i][j];
- ss << endl;
- }
- return ss.str();
- }
- //обработка матрицы
- elemtype** ProcessingMatrix(elemtype** matr, int row_counter, int column_counter) {
- /*Определить номер строки с минимальным количеством нулевых элементов и
- сложить элементы этой строки с соответствующими элементами всех нечетных строк.*/
- int a, b, min;
- int kmin = column_counter + 1;
- for (int a = 0; a < row_counter; a++)
- {
- int k = 0; //счётчик нулей в строке
- for (int b = 0; b < column_counter; b++)
- {
- if (matr[a][b] == 0)
- k++;
- }
- if (k < kmin)
- {
- min = a;
- kmin = k;
- }
- if (kmin == 0)
- break;
- };
- //проверка на нечётность строки
- for (a = 0; a < row_counter; a++)
- {
- if (a % 2 == 0 & a != min)
- for (b = 0; b < column_counter; b++)
- {
- matr[a][b] += matr[min][b];
- }
- }
- return matr;
- }
- //копирование элементов
- elemtype** Copy(elemtype** matr, int** copy_matr, int row_counter, int column_counter) {
- for (int i = 0; i < row_counter; i++)
- for (int j = 0; j < column_counter; j++)
- copy_matr[i][j] = matr[i][j];
- return copy_matr;
- }
- //Создание копии матрицы
- elemtype** CopyingMatrix(elemtype** matr, int row_counter, int column_counter, int& i) {
- elemtype** copy_matr = AllocatingMatrix(row_counter, column_counter);
- if (copy_matr == NULL)
- return NULL;
- return Copy(matr, copy_matr, row_counter, column_counter);
- }
- //загрузка матрицы
- Outcomes LoadingMatrix(const string& file, elemtype**& matr, int& row_counter, int& column_counter, MyUnion* VariosError = NULL) {
- Outcomes result;
- ifstream fin;
- fin.open(file);
- if (!fin.is_open()) {
- if (VariosError != NULL)
- VariosError->ErrOpen = errno;
- matr = NULL;
- row_counter = 0;
- column_counter = 0;
- return Outcomes::Error_Open;
- }
- result = CheckingMatrix(fin, row_counter, column_counter, VariosError);
- if (result != Outcomes::All_Good) {
- fin.close();
- matr = NULL;
- return result;
- }
- int i = 1;
- matr = AllocatingMatrix(row_counter, column_counter);
- if (matr == NULL) {
- fin.close();
- if (VariosError != NULL)
- VariosError->ErrAlloc = i;
- row_counter = 0;
- column_counter = 0;
- return Outcomes::Error_Of_Memory;
- }
- fin.clear();
- fin.seekg(0);
- ReadingMatrix(fin, matr, row_counter, column_counter);
- fin.close();
- return Outcomes::All_Good;
- }
- //главная
- int main() {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- for (;;) {
- cout << "Введите имя файла или \"*\" для завершения работы: ";
- if (cin.peek() == '*' && cin.rdbuf()->in_avail() == 2)
- return 0;
- MyUnion VariosError;
- int row_counter, column_counter;
- Outcomes result;
- string file;
- getline(cin, file); //ввод имени файла
- int** matr;
- if ((result = LoadingMatrix(file, matr, row_counter, column_counter, &VariosError)) != Outcomes::All_Good) {
- cout << "\nКод ошибки: " << result << endl;
- switch (result) {
- case Error_Open:
- cout << "Не удалось открыть файл \"" << file << "\"" << endl;
- cout << "Системный код ошибки \"errno\": " << VariosError.ErrOpen << endl;
- break;
- case File_Empty:
- cout << "\nФайл \"" << file << "\" пуст.";
- break;
- case Error_Elements: {
- ifstream fin(file); //открытие файла для чтения
- fin.seekg(VariosError.ErrElem.pos);
- string split;
- fin >> split;
- fin.close();
- cout << "\nОшибка в строке " << 1 + VariosError.ErrElem.row << " в столбце " << 1 + VariosError.ErrElem.column << '.';
- cout << "\nНекорректный элемент: \"" << split << "\"";
- break;
- }
- case Not_Rectangular:
- cout << "\nМатрица не прямоугольна, начиная со строки " << 1 + VariosError.ErrRectRow << '.';
- break;
- case Error_Of_Memory:
- if (VariosError.ErrAlloc == AllocBad) {
- cout << "\nОшибка выделения памяти под массив указателей для строк матрицы.\n";
- }
- else {
- cout << "\nОшибка выделения памяти под строки матрицы, начиная со строки " << VariosError.ErrAlloc + 1 << ".\n";
- }
- }
- cout << "\nНажмите любую клавишу, чтобы продолжить...";
- _getch();
- system("cls");
- continue;
- }
- cout << "\n\nИсходная матрица: \n\n";
- cout << MatrixToStr(matr, row_counter, column_counter);
- int i;
- elemtype** copy_matr = CopyingMatrix(matr, row_counter, column_counter, i); //выделение памяти на копию матрицы
- if (copy_matr = NULL) {
- DeletingMatrix(copy_matr, row_counter);
- if (i == AllocBad) {
- cout << "\nОшибка выделения памяти под массив указателей для строк копии матрицы.\n";
- }
- else {
- cout << "\nОшибка выделения памяти под строки копии матрицы, начиная со строки " << i + 1 << ".\n";
- }
- cout << "\nНажмите любую клавишу, чтобы продолжить...";
- _getch();
- system("cls");
- }
- ProcessingMatrix(matr, row_counter, column_counter); //функция обработки матрицы
- //вывод обработанной матрицы
- cout << "\n\nОбработанная матрица: \n\n";
- cout << MatrixToStr(matr, row_counter, column_counter);
- DeletingMatrix(matr, row_counter);
- DeletingMatrix(copy_matr, row_counter);
- cout << "\nНажмите любую клавишу, чтобы продолжить...";
- _getch();
- system("cls");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement