abubaca

calc

Dec 24th, 2018
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.99 KB | None | 0 0
  1. #include <conio.h>
  2. #include "windows.h"
  3. #include <iostream>
  4. #include <vector>
  5. #include <string>
  6. #include <functional>
  7. #include <cmath>
  8.  
  9. using namespace std;
  10. //размер окна консоли в символах
  11. #define WIDTH 80
  12. #define HEIGHT 30
  13. const double PI = 3.141592653589793238463; //задание константы PI
  14. HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); //получение дескриптора экранного буфера(требуется для функций консоли из windows.h)
  15.  
  16. void print(string &text, int x, int y) //вывод текста начиная с указанных координат. строка передаётся через ссылку чтобы избежать дублирования строки в памяти
  17. {
  18.     COORD pos; //задача координат
  19.     pos.X = x;
  20.     pos.Y = y;
  21.     SetConsoleCursorPosition(hCon, pos); //установка курсора в заданную позицию
  22.     cout << text; //вывод строки
  23. }
  24.  
  25. class menu
  26. {
  27.     vector <string> points; //вектор строк. пункты меню
  28.     vector <function<void()>> actions; //вектор указателей на функции, соответствующие пунктам меню. functional используется для передачи указателей на функций как часть класса
  29.     int point = 0; //текущий пункт меню
  30.     void show() //вывод меню на экран. предполагается, что добавлен хотя бы один пункт меню
  31.     {
  32.         system("cls"); //очистка окна консоли
  33.         int xMiddle = WIDTH / 2; //середина консольного окна
  34.         int yPart = HEIGHT / ((int)points.size() + 1); //вычисление высоты для вывода пунктов меню
  35.         for (int i = 0; i < (int)points.size(); i++) //здесь и на протяжении всего текста программы преобразование size_t в int для избегания warningов
  36.         {
  37.             if (i == point) //отображение текущего выбранного пункта меню
  38.             {
  39.                 string temp = "<<" + points[i] + ">>";
  40.                 print(temp, xMiddle - (int)temp.length() / 2, yPart*(i + 1)); //вывод пунта меню со смещением по x для центрации и по y в соответствии с номером
  41.             }
  42.             else
  43.                 print(points[i], xMiddle - (int)points[i].length() / 2, yPart*(i + 1));
  44.         }
  45.     }
  46.     void up()
  47.     {
  48.         point = point == 0 ? (int)points.size() - 1 : point - 1; //переключение на один пункт вверх
  49.     }
  50.     void down()
  51.     {
  52.         point = point == (int)points.size() - 1 ? 0 : point + 1; //переключение на один пункт вниз
  53.     }
  54.     void enter()
  55.     {
  56.         actions[point](); //выполнение действия текущего пункта
  57.     }
  58. public: //функции, доступные извне объекта
  59.     void add(string newP, function<void()> newA) //добавление нового пункта меню
  60.     {
  61.         points.push_back(newP);
  62.         actions.push_back(newA);
  63.     }
  64.     void get() //обработка нажатий клавиш
  65.     {
  66.         show(); //предварительный вывод меню
  67.         int button; //код введёной клавиши
  68.         while (true) //бесконечный цикл для обработки нажатий клавиш
  69.         {
  70.             button = _getch(); //получение кода нажатой клавиши без её вывода в буфер консоли
  71.             switch (button) //обработка нажатых клавиш
  72.             {
  73.             case 72: //стрелка вверх
  74.                 up();
  75.                 break;
  76.             case 80: //стрелка вниз
  77.                 down();
  78.                 break;
  79.             case 13: //enter
  80.                 enter();
  81.                 break;
  82.             case 27: //esc закрытие меню
  83.                 return;
  84.                 break;
  85.             }
  86.             show(); //вывод нового меню
  87.         }
  88.     }
  89. };
  90.  
  91. void calck_simple() //функция для рассчёта функций с двумя аргументами, задать которые можно одним символом
  92. {
  93.     system("cls");
  94.     int xMiddle = WIDTH / 2;
  95.     string output;
  96.     output = "You can chouse from actions: +, -, *, / and ^";
  97.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 - 3);
  98.     output = "Enter action:";
  99.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 - 2);
  100.     int action = 0; //хранение текущего действия
  101.     while (action != '+' && action != '-' && action != '*' && action != '/' && action != '^')  //ожидание ввода одного из поддерживаемых действий
  102.     {
  103.         action = _getch();
  104.         if (action == '+' || action == '-' || action == '*' || action == '/' || action != '^') //вывод действия если оно поддерживается
  105.             cout << (char)action;
  106.     }
  107.     output = "x";
  108.     output += (char)action; //при попытке написать в одну строку ошибка
  109.     output += "y";
  110.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 - 1);
  111.     double x, y, result;
  112.     output = "x=";
  113.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2);
  114.     cin >> x; //считывание x
  115.     output = "y=";
  116.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 + 1);
  117.     cin >> y; //считывание y
  118.     switch (action) //подсчёт результата
  119.     {
  120.     case '+':
  121.         result = x + y;
  122.         break;
  123.     case '-':
  124.         result = x - y;
  125.         break;
  126.     case '*':
  127.         result = x * y;
  128.         break;
  129.     case '/':
  130.         result = x / y;
  131.         break;
  132.     case '^':
  133.         result = pow(x, y);
  134.         break;
  135.     }
  136.     output = to_string(x);
  137.     output += (char)action;
  138.     output += to_string(y) + "=" + to_string(result);
  139.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 + 2);
  140.     int input = 0;
  141.     while (input != 27 && input != 13)
  142.     {
  143.         input = _getch();
  144.     }
  145. }
  146.  
  147. void calc_complex(string name, function<double(double)> fun) //получает на вход название функции и указатель на функцию, возвращающую значение этой функции
  148. {
  149.     system("cls");
  150.     int xMiddle = WIDTH / 2;
  151.     string output; //формирование строки для вывода
  152.     output = name + "(x)";
  153.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 - 1); //выведение строк последовательно, с центром в центре окна
  154.     output = "x=";
  155.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2);
  156.     double x;
  157.     cin >> x; //считывание аргумента
  158.     output = name + "(" + to_string(x) + ")=" + to_string(fun(x));  //подсчёт значения функции
  159.     print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 + 1);
  160.     int input = 0; //хранение последней нажатой клавиши
  161.     while (input != 27 && input != 13) //выход в меню при нажатии esc или enter
  162.     {
  163.         input = _getch();
  164.     }
  165. }
  166. //подсчёт сложных функций
  167. double sin_grad(double x)
  168. {
  169.     return sin((x * PI) / 180);
  170. }
  171.  
  172. double cos_grad(double x)
  173. {
  174.     return cos((x * PI) / 180);
  175. }
  176.  
  177. double tan_grad(double x)
  178. {
  179.     return tan((x * PI) / 180);
  180. }
  181.  
  182. double sqrt_double(double x)
  183. {
  184.     return sqrt(x);
  185. }
  186.  
  187. int main()
  188. {
  189.     string resize = "mode " + to_string(WIDTH) + ", " + to_string(HEIGHT); //формирование строки для изменения размера консоли и отключения полосы прокрутки
  190.     system(resize.c_str()); //выполнение системной команды для изменения размера консоли с предварительным преобразованием строки в C-style строку(требуется как аргумент в system)
  191.     setlocale(LC_ALL, "Russian"); //включение русской кодировки
  192.     //формирование цвета текста и фона консоли http://vsokovikov.narod.ru/New_MSDN_API/Console/scrbuf.htm#attrib_char_cons
  193.     SetConsoleTextAttribute(hCon, BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); //изменение цвета текста и фона консоли
  194.     menu complex_functions; //меню для сложных функций
  195.     complex_functions.add("sin", bind(calc_complex, "sin", sin_grad));
  196.     complex_functions.add("cos", bind(calc_complex, "cos", cos_grad));
  197.     complex_functions.add("tg", bind(calc_complex, "tg", tan_grad));
  198.     complex_functions.add("sqrt", bind(calc_complex, "sqrt", sqrt_double));
  199.     menu main_menu;//главное меню
  200.     main_menu.add("complex functions", bind(&menu::get, complex_functions)); //передача указателя на функцию часть класса
  201.     main_menu.add("simple function", calck_simple);
  202.     main_menu.add("exit", bind(exit,0)); //преобразование void (*)(int) в void(*)() с предопределением аргумента
  203.     while (true) //запрет выхода по esc из главного меню
  204.         main_menu.get();
  205. }
Advertisement
Add Comment
Please, Sign In to add comment