Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Определить номер строки с минимальным количеством нулевых элементов и
- //сложить элементы этой строки с соответствующими элементами всех нечетных строк.
- #include <iostream> //объявляет объекты, управляющие чтением из стандартных потоков и записью в них
- #include <iomanip> //определение нужного числа манипуляторов, каждый из которых принимает один аргумент
- #include <Windows.h> //функции WinAPI, константы, типы, прототипы и др.
- #include <conio.h> //объявляет несколько библиотечных функций для работы с «консольным вводом и выводом» программы (_getch())
- #include <fstream> //определяет несколько классов, поддерживающих операции iostreams для последовательностей, хранящихся во внешних файлах
- #include <sstream> //определяет несколько шаблонов классов, поддерживающих операции iostream для последовательностей, хранящихся в выделенном объекте массива
- #include <cerrno> //имена, объявленные с помощью внешней компоновки в заголовке стандартной библиотеки C, объявляются в std пространстве имен
- #include <string> //методы и переменные для организации работы со строками
- using namespace std; //std-пространство имён, содержащее все типы и функции стандартной библиотеки с++
- #define AllocGood -2 //Выделяет блок памяти указанного размера из подраспределителя кэширования среды параллелизма
- #define AllocBad -1
- // внутренний код ошибки
- //Объявляет перечисление в области видимости пространства имен, которое является определяемым пользователем типом,
- //состоящим из ряда именованных констант, называемых перечислителями.
- enum Outcomes { //перечисление возвращаемых значений
- All_Good, // 0 - Все хорошо
- Error_Open,// 1 - Ошибка открытия файла
- File_Empty,// 2 - Пустой файл
- Error_Elements,// 3 - Некорректный элемент
- Not_Rectangular,//4 - Непрямоугольная
- Error_Of_Memory// 5 - Ошибка выделения памяти
- };
- 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;
- }
- //выделение памяти
- int** AllocatingMatrix(int row_counter, int column_counter) {
- int** matr = NULL;
- int i = AllocBad;
- try {
- matr = new int* [row_counter];
- for (i = 0; i < row_counter; i++)
- matr[i] = new int[column_counter];
- }
- catch (...) {
- if (matr != NULL)
- DeletingMatrix(matr, i);
- return NULL;
- }
- i = AllocGood;
- return matr;
- }
- //чтение матрицы
- int** 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) {
- ostringstream ss; //класс вывода строк
- for (int i = 0; i < row_counter; i++) {
- for (int j = 0; j < column_counter; j++)
- ss << setw(number) << matr[i][j];
- ss << endl;
- }
- return ss.str();
- }
- //обработка матрицы
- int** 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;
- }
- };
- for (a = 0; a < row_counter; a++) //проверка по строкам
- {
- for (b = 0; b < column_counter; b++) //проверка по столбцам
- {
- if (a % 2 == 0 & a != min) //проверка на нечётность строки
- matr[a][b] = matr[min][b] + matr[a][b];
- }
- }
- return matr;
- }
- //копирование элементов
- int** 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;
- }
- //Создание копии матрицы
- int** CopyingMatrix(elemtype** matr, int row_counter, int column_counter, int& i) {
- int** 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) {
- 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 << "Не удалось открыть файл." << 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;
- int** copy_matr = CopyingMatrix(matr, row_counter, column_counter, i); //указатель на указатель копии матрицы
- if (i == AllocBad) {
- cout << "\nОшибка выделения памяти под массив указателей для строк матрицы.\n";
- }
- else if (i >= 0) {
- cout << "\nОшибка выделения памяти под строки матрицы, начиная со строки " << i + 1 << ".\n";
- }
- ProcessingMatrix(matr, row_counter, column_counter);
- //вывод обработанной матрицы
- int** ProcessingMatrix(elemtype **matr, int row_counter, int column_counter); {
- cout << endl;
- cout << "Минимальное кол-во нулей содержится в строке " << min + 1;
- }
- 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");
- continue;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement