Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <iostream>
- #include <stdlib.h>
- #include <Windows.h>
- #include <string>
- #include <fstream>
- #include <iomanip>
- #include <sstream>
- using namespace std;
- bool onlyNum(const string s)
- {
- bool decimal = false; //Переменная, отвечающая за наличие символа - разделителя разрядов в числе
- bool sign = false; //Переменная, отвечающая за наличие знака у числа
- bool pow = false;//Переменная, отвечающая за наличие сокращения экспоненциальной степени у числа
- for (unsigned int i = 0; i < s.length(); i++) //Перебирая все символы строки
- {
- if (s.at(i) == 'e' || s.at(i) == 'E')//Если находим символ степени
- if (!pow && i != 0 && i != s.length() - 1)//Если у него хотя бы теоретически есть валидные значения основания и степени и мы его еще не находили
- pow = true;//Отмечаем, что нашли
- else//Иначе
- return false;//Неверный ввод
- else if (s.at(i) == '+' || s.at(i) == '-')//Если находим знак
- if (!sign && i == 0 && s.length() > 1)//Если он еще не был найден и мы находимся на 1 символе
- sign = true;//Отмечаем, что нашли его
- else//Иначе
- return false;//Неверный ввод
- else if (s.at(i) == '.' || s.at(i) == ',') //Если находим символ-разделитель разрядов
- if (!decimal) //Если он еще не был найден
- decimal = true; //Отмечаем, что нашли его
- else //Если мы его уже находили и нашли еще раз
- return false; //Неверный ввод
- else if ((s.at(i) < '0' || s.at(i) > '9') && s.at(i) != ' ' && s.at(i) != '\t') //Если встречаем не число и при этом не символ-разделитель
- return false; //Неверный ввод
- }
- return true; //Верный ввод
- }
- void deleteMatr(double **matr, const unsigned int size) {
- for (unsigned int i = size; i > -1; i--)//Проходя по всем строкам, для которых уже выделена память
- delete(matr[i]);//Очищаем ее
- delete(matr);//очищаем сам указатель
- }
- double **loadFile(istream &in, ostream &out, unsigned int &rows, unsigned int &cols) {
- string fileName;
- string t;
- stringstream res, buf;
- ifstream fin;
- int tcols;
- bool failed = false;
- while (!fin.is_open()) { //Пока не открыли файл
- if (failed)
- cout << "Неудачная попытка открытия\n";
- cout << "Введите имя файла: ";
- getline(cin, fileName); //Считываем имя
- fin.open(fileName); //Пытаемся открыть
- failed = true; //Если файл открылся, цикл не запустится ещё раз, в другом случае скажем об этом в начала следующей итерации
- }
- while (getline(fin, t))
- {
- if (t.find('0') != string::npos //Проверяем наличие цифр(теоретических элементов в строке)
- || t.find('1') != string::npos
- || t.find('2') != string::npos
- || t.find('3') != string::npos
- || t.find('4') != string::npos
- || t.find('5') != string::npos
- || t.find('6') != string::npos
- || t.find('7') != string::npos
- || t.find('8') != string::npos
- || t.find('9') != string::npos)
- {
- tcols = 0;
- buf.str(string());
- buf.clear();
- buf << t;//Сохраняем в sstream для подсчета столбцов
- res << t;//Сохраняем для записи в матрицу
- res << ' ';//Отделяем строки
- while (buf >> t)
- tcols++;//Подсчитываем столбцы
- if (cols == 0)//Если ещё не было известно количество столбцов
- cols = tcols;//Сохраняем
- else if (tcols != cols) {//Иначе, если количество столбцов в очередной стркое не совпадает с предыдущими
- cout << "Матрица не является прямоугольной в строке " << rows + 1 << '\n';
- return nullptr;
- }
- rows++;
- }
- }
- double** matr = new(std::nothrow) double*[rows]; //Выделяем память под массив
- if (matr == nullptr) { //Обработка проблем с выделением памяти
- deleteMatr(matr, 0);//Очищаем матрицу
- cout << "Неудачная попытка выделения памяти под массив\n";
- fin.close();//Закрываем поток
- return nullptr;
- }
- for (unsigned int i = 0; i < rows; i++) {
- matr[i] = new(std::nothrow) double[cols];//Выделяем память под очередную строку
- if (matr[i] == nullptr) { //Обработка проблем с выделением памяти
- deleteMatr(matr, i);//Очищаем матрицу
- cout << "Неудачная попытка выделения памяти под массив\n";
- fin.close();//Закрываем поток
- return nullptr;
- }
- else {
- for (unsigned int j = 0; j < cols; j++) {//Для каждого элемента
- res >> t; //Считываем его
- if (onlyNum(t)) { //Если он валидный
- try {
- while (t.find(",") != t.npos)
- t.replace(t.find(","), 1, ".");
- matr[i][j] = stod(t.c_str()); //Пытаемся перевести в double
- }
- catch (out_of_range err) { //Обрабатываем переполнение
- cout << "Обнаружено переполнение типа в значении \"" << t << "\" при чтении элемента " << i + 1 << " строки " << j + 1 << " столбца\n";
- deleteMatr(matr, i);//Очищаем матрицу
- fin.close();//Закрываем поток
- return nullptr;
- }
- }
- else { //Иначе
- cout << "Неверный ввод значения \"" << t << "\" при чтении элемента " << i + 1 << " строки " << j + 1 << " столбца\n";
- deleteMatr(matr, i);//Очищаем матрицу
- fin.close();//Закрываем поток
- return nullptr;
- }
- }
- }
- }
- fin.close(); //Закрываем поток
- return matr;
- }
- string getMatr(double **matr, const unsigned int rows, const unsigned int cols) {
- stringstream s;
- //Записываем матрицу в sstream с последующим преобразованием в string
- for (unsigned int i = 0; i < rows; i++) {
- for (unsigned int j = 0; j < cols; j++)
- s << setw(12) << matr[i][j] << ' ';
- s << '\n';
- }
- return s.str();
- }
- void showData(ostream &out, double **matr, const unsigned int rows, const unsigned int cols) {
- out << getMatr(matr, rows, cols);//Выводим созданную строку в нужный поток
- }
- void workWithData(double **matr, const unsigned int rows, const unsigned int cols) {
- double pr;
- int k = 0;
- cout << "Считанная матрица\n";
- showData(cout, matr, rows, cols); //Выводим изначальну юматрицу
- for (unsigned int i = 0; i < rows; i += 2) { //Проходя по всем нечетным строкам
- pr = 1; //Изначально произведение равно 1
- for (unsigned int j = 0; j < cols; j++) { //Проходя по всем столбцам
- if (matr[i][j] < 0) { //Если элемент отрицательный
- pr *= matr[i][j]; //Изменяем произведение
- k++;//И количество отрицательных элементов
- }
- }
- if (pr < 0) //Если произведение отрицательно
- for (unsigned int j = 0; j < cols; j++) { //Заменяем всю строку нулями
- matr[i][j] = 0;
- }
- }
- cout << "Количество отрицательных элементов в нечетных строках: " << k << '\n';
- cout << "Измененная матрица\n";
- showData(cout, matr, rows, cols);//Выводим измененную матрицу
- }
- int main() {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);//Русский язык))
- double **matr = nullptr;
- unsigned int rows = 0, cols = 0;
- matr = loadFile(cin, cout, rows, cols);//Загружаем файл
- if (matr != nullptr) { //Если матрица загрузилась без проблем
- workWithData(matr, rows, cols);//Работаем с ней
- deleteMatr(matr, rows - 1);//Очищаем выделенную память
- }
- cout << "Нажмите любую кнопку чтобы продолжить...\n";
- getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement