Загрузка данных


#include <iostream>
#include <vector>
#include <exception>
#include <stdexcept>

using namespace std;

// ==================== ФУНКЦИЯ ДЛЯ ВВОДА ЦЕЛЫХ ЧИСЕЛ С ПРОВЕРКОЙ ====================
int inputInt(const char* prompt) {
    int value;
    bool validInput = false;
        
    cout << prompt;
        
    for (int attempt = 0; attempt < 3 && !validInput; attempt++) {
        if (attempt > 0) {
            cout << "Oshibka! Vvedite chislo: ";
        }
            
        if (cin >> value) {
            if (value > 0) {
                validInput = true;
            } else {
                cout << "Chislo dolzhno byt' bol'she 0. ";
                cin.clear();
                cin.ignore(10000, '\n');
            }
        } else {
            cin.clear();
            cin.ignore(10000, '\n');
            cout << "Nekorrektnyy vvod. ";
        }
    }
        
    if (!validInput) {
        cout << "Prekratnyy vvod. Ustanovleno znachenie 1." << endl;
        value = 1;
    }
    return value;
}

// ==================== СОБСТВЕННЫЕ КЛАССЫ ИСКЛЮЧЕНИЙ ====================
class InvalidIndexException : public exception {
public:
    const char* what() const noexcept override {
        return "Oshibka: Popytka dostupa k elementu s nevernym indeksom!";
    }
};

class MatrixHasZeroException : public exception {
private:
    string operation;
public:
    MatrixHasZeroException(const string& op) : operation(op) {}
    
    const char* what() const noexcept override {
        static string msg;
        msg = "Oshibka: Popytka " + operation + " matric, soderzhashchih nuli!";
        return msg.c_str();
    }
};

// ==================== КЛАСС MATRIX ====================
class Matrix {
private:
    vector<vector<int>> data;
    int rows;
    int cols;
    
    // Проверка наличия нулей в матрице
    bool hasZeros() const {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (data[i][j] == 0) {
                    return true;
                }
            }
        }
        return false;
    }
    
public:
    // Конструктор
    Matrix(int r, int c) : rows(r), cols(c) {
        data.resize(rows, vector<int>(cols, 0));
    }
    
    // Ввод матрицы
    void input() {
        cout << "Vvedite elementy matricy " << rows << "x" << cols << ":" << endl;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                char prompt[100];
                sprintf(prompt, "  [%d][%d] = ", i, j);
                data[i][j] = inputInt(prompt);
            }
        }
    }
    
    // Вывод матрицы
    void print() const {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                cout << data[i][j] << "\t";
            }
            cout << endl;
        }
    }
    
    // Доступ к элементу с проверкой индекса (генерирует исключение)
    int& at(int i, int j) {
        if (i < 0 || i >= rows || j < 0 || j >= cols) {
            throw InvalidIndexException();
        }
        return data[i][j];
    }
    
    const int& at(int i, int j) const {
        if (i < 0 || i >= rows || j < 0 || j >= cols) {
            throw InvalidIndexException();
        }
        return data[i][j];
    }
    
    // Сложение матриц (генерирует исключение при наличии нулей)
    Matrix add(const Matrix& other) const {
        if (rows != other.rows || cols != other.cols) {
            throw invalid_argument("Matricy raznogo razmera!");
        }
        
        if (hasZeros() || other.hasZeros()) {
            throw MatrixHasZeroException("slozheniya");
        }
        
        Matrix result(rows, cols);
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                result.data[i][j] = data[i][j] + other.data[i][j];
            }
        }
        return result;
    }
    
    // Вычитание матриц (генерирует исключение при наличии нулей)
    Matrix subtract(const Matrix& other) const {
        if (rows != other.rows || cols != other.cols) {
            throw invalid_argument("Matricy raznogo razmera!");
        }
        
        if (hasZeros() || other.hasZeros()) {
            throw MatrixHasZeroException("vychitaniya");
        }
        
        Matrix result(rows, cols);
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                result.data[i][j] = data[i][j] - other.data[i][j];
            }
        }
        return result;
    }
    
    // Перегрузка оператора + (использует add)
    Matrix operator+(const Matrix& other) const {
        return add(other);
    }
    
    // Перегрузка оператора - (использует subtract)
    Matrix operator-(const Matrix& other) const {
        return subtract(other);
    }
    
    // Геттеры
    int getRows() const { return rows; }
    int getCols() const { return cols; }
    
    // Проверка наличия нулей
    bool containsZeros() const {
        return hasZeros();
    }
};

// ==================== ОСНОВНАЯ ЧАСТЬ: РАБОТА С МАТРИЦАМИ И ИСКЛЮЧЕНИЯМИ ====================
int main() {
    cout << "==========================================" << endl;
    cout << "LABORATORNAYa RABOTA: MATRICY I ISKLJUChENIJa" << endl;
    cout << "==========================================" << endl;
    
    int rows, cols;
    cout << "\nVvedite kolichestvo strok i stolbcov dlya matric: ";
    rows = inputInt("Stroki: ");
    cols = inputInt("Stolbcy: ");
    
    Matrix A(rows, cols);
    Matrix B(rows, cols);
    
    cout << "\nVvod matricy A:" << endl;
    A.input();
    
    cout << "\nVvod matricy B:" << endl;
    B.input();
    
    cout << "\nMatrica A:" << endl;
    A.print();
    
    cout << "\nMatrica B:" << endl;
    B.print();
    
    // Демонстрация доступа к элементу с проверкой индекса
    cout << "\n--- Proverka dostupa k elementam ---" << endl;
    try {
        int i, j;
        cout << "Vvedite indeksy elementa (i j): ";
        cin >> i >> j;
        cout << "Element A[" << i << "][" << j << "] = " << A.at(i, j) << endl;
    } catch (const InvalidIndexException& e) {
        cout << e.what() << endl;
    } catch (const exception& e) {
        cout << "Neizvestnaya oshibka: " << e.what() << endl;
    }
    
    // Демонстрация сложения матриц с проверкой на нули
    cout << "\n--- Slozhenie matric ---" << endl;
    try {
        Matrix C = A.add(B);
        cout << "Rezul'tat slozheniya:" << endl;
        C.print();
    } catch (const MatrixHasZeroException& e) {
        cout << e.what() << endl;
        cout << "Matrica A soderzhit nuli: " << (A.containsZeros() ? "da" : "net") << endl;
        cout << "Matrica B soderzhit nuli: " << (B.containsZeros() ? "da" : "net") << endl;
    } catch (const invalid_argument& e) {
        cout << e.what() << endl;
    }
    
    // Демонстрация вычитания матриц с проверкой на нули
    cout << "\n--- Vychitanie matric ---" << endl;
    try {
        Matrix D = A.subtract(B);
        cout << "Rezul'tat vychitaniya:" << endl;
        D.print();
    } catch (const MatrixHasZeroException& e) {
        cout << e.what() << endl;
        cout << "Matrica A soderzhit nuli: " << (A.containsZeros() ? "da" : "net") << endl;
        cout << "Matrica B soderzhit nuli: " << (B.containsZeros() ? "da" : "net") << endl;
    } catch (const invalid_argument& e) {
        cout << e.what() << endl;
    }
    
    return 0;
}