Advertisement
Kentoo

O#1

Sep 19th, 2018
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.35 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <stdlib.h>
  4. #include <Windows.h>
  5. #include <string>
  6. #include <fstream>
  7. #include <iomanip>
  8.  
  9. using namespace std;
  10.  
  11. bool    onlyNum(const string s)
  12. {
  13.     bool decimal = false; //Переменная, отвечающая за наличие символа - разделителя разрядов в числе
  14.     bool sign = false; //Переменная, отвечающая за наличие знака у числа
  15.     bool pow = false;//Переменная, отвечающая за наличие сокращения экспоненциальной степени у числа
  16.     for (int i = 0; i < s.length(); i++) //Перебирая все символы строки
  17.     {
  18.         if (s.at(i) == 'e' || s.at(i) == 'E')//Если находим символ степени
  19.             if (!pow && i != 0 && i != s.length() - 1)//Если у него хотя бы теоретически есть валидные значения основания и степени и мы его еще не находили
  20.                 pow = true;//Отмечаем, что нашли
  21.             else//Иначе
  22.                 return false;//Неверный ввод
  23.         else if (s.at(i) == '+' || s.at(i) == '-')//Если находим знак
  24.             if (!sign && i == 0 && s.length() > 1)//Если он еще не был найден и мы находимся на 1 символе
  25.                 sign = true;//Отмечаем, что нашли его
  26.             else//Иначе
  27.                 return false;//Неверный ввод
  28.         else if (s.at(i) == '.' || s.at(i) == ',') //Если находим символ-разделитель разрядов
  29.             if (!decimal) //Если он еще не был найден
  30.                 decimal = true; //Отмечаем, что нашли его
  31.             else             //Если мы его уже находили и нашли еще раз
  32.                 return false; //Неверный ввод
  33.         else if ((s.at(i) < '0' || s.at(i) > '9') && s.at(i) != ' ' && s.at(i) != '\t') //Если встречаем не число и при этом не символ-разделитель
  34.             return false; //Неверный ввод
  35.     }
  36.     return true; //Верный ввод
  37. }
  38.  
  39. double  *createFile(unsigned int &size) {
  40.     string      s;
  41.     string      c;
  42.     string      fileName;
  43.     ofstream    fout;
  44.     bool        failed = false;
  45.  
  46.     while (true) {
  47.         cout << "Введите количество элементов массива" << endl;
  48.         getline(cin, s); //Считываем количество элементов
  49.         if (atoi(s.c_str()) == atof(s.c_str()) && onlyNum(s) && atoi(s.c_str()) > -1) { //Если число целое, валидное и как минимум 0
  50.             size = atoi(s.c_str()); //Записываем его
  51.             break;
  52.         }
  53.         else //Иначе невалидный ввод
  54.             cout << "Неверный ввод\n\n";
  55.     }
  56.     cout << '\n';
  57.     double* arr = new(std::nothrow) double[size]; //Выделяем память под массив, флаг nothrow скидывает обработку возможных проблем выделения памяти на нас
  58.     if (arr == nullptr) { //Если память не выделилась
  59.         delete(arr); //Очищаем указатель
  60.         cout << "Неудачная попытка выделения памяти под массив\n";
  61.         getchar();
  62.         return nullptr; //Возвращаем нулевой указатель
  63.     }
  64.     for (int i = 0; i < size; i++) { //Цикл чтения массива
  65.         cout << "Введите " << i + 1 << " элемент массива : ";
  66.         getline(cin, s); //Считываем очередной элемент
  67.         while (!onlyNum(s)) { //Пока он не валиден
  68.             cout << "Неверный ввод " << i + 1 << " элемента массива, попробуйте ещё раз : ";
  69.             getline(cin, s); //Считываем ещё один
  70.         }
  71.         while (true) {
  72.             try {
  73.                 while (s.find(",") != s.npos)
  74.                     s.replace(s.find(","), 1, ".");
  75.                 arr[i] = stod(s.c_str()); //Пытаемся перевести в double
  76.                 break;
  77.             }
  78.             catch (out_of_range err) { //Обрабатываем переполнение
  79.                 cout << "Переполнение типа " << i + 1 << " элемента массива, попробуйте ещё раз : ";
  80.                 getline(cin, s); //Считываем ещё один
  81.             }
  82.         }
  83.     }
  84.     while (!fout.is_open()) { //Работа с файлом
  85.         cout << "\nВведите имя файла : ";
  86.         getline(cin, fileName); //Считываем имя
  87.         fout.open(fileName, ios::_Nocreate | ios::binary); //Открываем без удаления существующего в бинарном режиме
  88.         if (fout.is_open()) { //Если смогли открыть
  89.             cout << "Обнаружен файл с таким именем, разрешить перезаписать? (y - да, n - нет)\n";
  90.             getline(cin, c); //Считываем ответ пользователя
  91.             while (c.at(0) != 'y' && c.at(0) != 'Y' && c.at(0) != 'у' && c.at(0) != 'У' && c.at(0) != 'n' && c.at(0) != 'N' && c.length() > 1) { //Если он не валидный
  92.                 cout << "Введен неправильный ответ, попробуйте еще раз" << endl;
  93.                 getline(cin, c); //Считываем ещё один
  94.             }
  95.             switch (c.at(0)) { //Обрабатываем ответ пользователя
  96.             case 'y':
  97.             case 'Y':
  98.             case 'у':
  99.             case 'У':
  100.                 fout.close();
  101.                 fout.open(fileName, ios::trunc | ios::binary); //Если он да, то перезаписываем файл
  102.                 break;
  103.             case 'n':
  104.             case 'N':
  105.                 fout.close(); //Если нет, то просто закрываем поток
  106.                 break;
  107.             default:
  108.                 break;
  109.             }
  110.         }
  111.         else {
  112.             fout.close();
  113.             fout.open(fileName, ios::binary); //Если не открыли, значит такого файла нет и просто создаем его
  114.         }
  115.     }
  116.     fout.write((char*)arr, size * sizeof(double)); //Записываем в файл массив
  117.     fout.close(); //Закрываем поток
  118.     return arr;
  119. }
  120.  
  121. double  *loadFile(unsigned int  &size) {
  122.     string      fileName;
  123.     ifstream    fin;
  124.     int         t;
  125.     double      a;
  126.     bool        failed = false;
  127.  
  128.     while (!fin.is_open()) { //Пока не открыли файл
  129.         if (failed)
  130.             cout << "Неудачная попытка открытия\n";
  131.         cout << "Введите имя файла: ";
  132.         getline(cin, fileName); //Считываем имя
  133.         fin.open(fileName, ios::binary); //Пытаемся открыть
  134.         failed = true; //Если файл открылся, цикл не запустится ещё раз, в другом случае скажем об этом в начала следующей итерации
  135.     }
  136.     fin.seekg(0, ios::end); //Двигаем указател ьв конец файла
  137.     t = fin.tellg(); //Берем его позицию
  138.     size = t / sizeof(double); //Узнаем размер массива
  139.     fin.seekg(0, ios::beg); //Двигаем указатель в начало
  140.     double* arr = new(std::nothrow) double[size]; //Выделяем память под массив
  141.     if (arr == nullptr) { //Обработка проблем с выделением памяти
  142.         delete(arr);
  143.         cout << "Неудачная попытка выделения памяти под массив\n";
  144.         fin.close();
  145.         getchar();
  146.         return nullptr;
  147.     }
  148.     fin.clear();
  149.     fin.read((char*)arr, size * sizeof(double)); //Считываем массив без проверки входных данных
  150.     fin.close(); //Закрываем поток
  151.     return arr;
  152. }
  153.  
  154. void    showData(double *arr, unsigned int size) {
  155.     cout << setw(10) << "Номера: ";
  156.     for (unsigned int i = 0; i < size; i++) { //Выводим номера элементов массива
  157.         cout << setw(8) << i << ' ';
  158.     }
  159.     cout << setw(10) << "\nЭлементы: ";
  160.     for (unsigned int i = 0; i < size; i++) { //Выводим элементы массива
  161.         cout << setw(8) << arr[i] << ' ';
  162.     }
  163.     cout << '\n';
  164. }
  165.  
  166. void    workWithFile(double *arr, unsigned int size) {
  167.     double  min = arr[0]; //Изначально минимальный элемент - первый
  168.     for (unsigned int i = 1; i < size; i++) //Проходя по всему циклу, находим минимальынй элемент
  169.         if (min < arr[i])
  170.             min = arr[i];
  171.     min = (min > 18.3) ? (2) : (0.5); //Если он больше 18.3, то наш множитель 2, в другом случае 1/2
  172.     for (unsigned int i = 0; i < size; i++)//Применяем множитель к каждому элементу массива
  173.         arr[i] = arr[i] * min;
  174.     showData(arr, size); //Выводим измененный массив
  175. }
  176.  
  177. void    menu() {
  178.     cout << "1. Создать файл с исходными данными\n"
  179.         << "2. Загрузить исходные данные\n"
  180.         << "3. Вывести исходные данные\n"
  181.         << "4. Обработать данные\n"
  182.         << "5. Завершить работу с программой\n";
  183. }
  184.  
  185. double  *menu_select(string c, double *arr, unsigned int &size) {
  186.     if (c.length() != 1) //Если введен не 1 символ, то ввод не валиден
  187.         cout << "Неверный ввод\n\n";
  188.     else
  189.         switch (c.c_str()[0]) {
  190.         case '1':
  191.         {
  192.             system("cls");//Очищаем экран
  193.             arr = createFile(size);//Создаем файл и возвращаем считанный массив
  194.             if (arr == nullptr) //Проверяем, что память под него выделилась
  195.                 exit(1); //Если нет, то выходим из программы
  196.             break;
  197.         }
  198.         case '2':
  199.         {
  200.             system("cls");//Очищаем экран
  201.             arr = loadFile(size);//Читаем файл и возвращаем считанный массив
  202.             if (arr == nullptr) //Проверям, что памят ьвыделена
  203.                 exit(1); //Если нет, то выходим
  204.             showData(arr, size); //Выводим считанные данные
  205.             break;
  206.         }
  207.         case '3':
  208.         {
  209.             system("cls");//Очищаем экран
  210.             if (arr != nullptr) //Если данные уже были считаны
  211.                 showData(arr, size); //Выводим их
  212.             else//Иначе
  213.                 cout << "Не обнаружены данные для работы\n";
  214.             break;
  215.         }
  216.         case '4':
  217.         {
  218.             system("cls");//Очищаем экран
  219.             if (arr != nullptr)//Если данные уже были считаны
  220.                 workWithFile(arr, size);//Работаем с ними
  221.             else//Иначе
  222.                 cout << "Не обнаружены данные для работы\n";
  223.             break;
  224.         }
  225.         case '5':
  226.         {
  227.             delete(arr);//очищаем выделенную память
  228.             exit(1);//Выходим из программы
  229.             break;
  230.         }
  231.         default:
  232.         {
  233.             cout << "Неверный ввод\n";
  234.             break;
  235.         }
  236.         }
  237.     return arr;
  238. }
  239.  
  240. int     main() {
  241.     SetConsoleCP(1251);
  242.     SetConsoleOutputCP(1251);//Русский язык))
  243.     string          c;
  244.     double          *arr = nullptr;
  245.     unsigned int    size = 0;
  246.     while (true)
  247.     {
  248.         system("cls");//Очищаем экран
  249.         menu();//Выводим меню
  250.         getline(cin, c);//Считываем ответ пользователя
  251.         arr = menu_select(c, arr, size);//Выполняем нужное действие
  252.         cout << "Нажмите любую кнопку чтобы продолжить...\n";
  253.         getchar();
  254.     }
  255.     return 0;
  256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement