Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <conio.h>
- #include "windows.h"
- #include <iostream>
- #include <vector>
- #include <string>
- #include <functional>
- #include <cmath>
- using namespace std;
- //размер окна консоли в символах
- #define WIDTH 80
- #define HEIGHT 30
- const double PI = 3.141592653589793238463; //задание константы PI
- HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); //получение дескриптора экранного буфера(требуется для функций консоли из windows.h)
- void print(string &text, int x, int y) //вывод текста начиная с указанных координат. строка передаётся через ссылку чтобы избежать дублирования строки в памяти
- {
- COORD pos; //задача координат
- pos.X = x;
- pos.Y = y;
- SetConsoleCursorPosition(hCon, pos); //установка курсора в заданную позицию
- cout << text; //вывод строки
- }
- class menu
- {
- vector <string> points; //вектор строк. пункты меню
- vector <function<void()>> actions; //вектор указателей на функции, соответствующие пунктам меню. functional используется для передачи указателей на функций как часть класса
- int point = 0; //текущий пункт меню
- void show() //вывод меню на экран. предполагается, что добавлен хотя бы один пункт меню
- {
- system("cls"); //очистка окна консоли
- int xMiddle = WIDTH / 2; //середина консольного окна
- int yPart = HEIGHT / ((int)points.size() + 1); //вычисление высоты для вывода пунктов меню
- for (int i = 0; i < (int)points.size(); i++) //здесь и на протяжении всего текста программы преобразование size_t в int для избегания warningов
- {
- if (i == point) //отображение текущего выбранного пункта меню
- {
- string temp = "<<" + points[i] + ">>";
- print(temp, xMiddle - (int)temp.length() / 2, yPart*(i + 1)); //вывод пунта меню со смещением по x для центрации и по y в соответствии с номером
- }
- else
- print(points[i], xMiddle - (int)points[i].length() / 2, yPart*(i + 1));
- }
- }
- void up()
- {
- point = point == 0 ? (int)points.size() - 1 : point - 1; //переключение на один пункт вверх
- }
- void down()
- {
- point = point == (int)points.size() - 1 ? 0 : point + 1; //переключение на один пункт вниз
- }
- void enter()
- {
- actions[point](); //выполнение действия текущего пункта
- }
- public: //функции, доступные извне объекта
- void add(string newP, function<void()> newA) //добавление нового пункта меню
- {
- points.push_back(newP);
- actions.push_back(newA);
- }
- void get() //обработка нажатий клавиш
- {
- show(); //предварительный вывод меню
- int button; //код введёной клавиши
- while (true) //бесконечный цикл для обработки нажатий клавиш
- {
- button = _getch(); //получение кода нажатой клавиши без её вывода в буфер консоли
- switch (button) //обработка нажатых клавиш
- {
- case 72: //стрелка вверх
- up();
- break;
- case 80: //стрелка вниз
- down();
- break;
- case 13: //enter
- enter();
- break;
- case 27: //esc закрытие меню
- return;
- break;
- }
- show(); //вывод нового меню
- }
- }
- };
- void calck_simple() //функция для рассчёта функций с двумя аргументами, задать которые можно одним символом
- {
- system("cls");
- int xMiddle = WIDTH / 2;
- string output;
- output = "You can chouse from actions: +, -, *, / and ^";
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 - 3);
- output = "Enter action:";
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 - 2);
- int action = 0; //хранение текущего действия
- while (action != '+' && action != '-' && action != '*' && action != '/' && action != '^') //ожидание ввода одного из поддерживаемых действий
- {
- action = _getch();
- if (action == '+' || action == '-' || action == '*' || action == '/' || action != '^') //вывод действия если оно поддерживается
- cout << (char)action;
- }
- output = "x";
- output += (char)action; //при попытке написать в одну строку ошибка
- output += "y";
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 - 1);
- double x, y, result;
- output = "x=";
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2);
- cin >> x; //считывание x
- output = "y=";
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 + 1);
- cin >> y; //считывание y
- switch (action) //подсчёт результата
- {
- case '+':
- result = x + y;
- break;
- case '-':
- result = x - y;
- break;
- case '*':
- result = x * y;
- break;
- case '/':
- result = x / y;
- break;
- case '^':
- result = pow(x, y);
- break;
- }
- output = to_string(x);
- output += (char)action;
- output += to_string(y) + "=" + to_string(result);
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 + 2);
- int input = 0;
- while (input != 27 && input != 13)
- {
- input = _getch();
- }
- }
- void calc_complex(string name, function<double(double)> fun) //получает на вход название функции и указатель на функцию, возвращающую значение этой функции
- {
- system("cls");
- int xMiddle = WIDTH / 2;
- string output; //формирование строки для вывода
- output = name + "(x)";
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 - 1); //выведение строк последовательно, с центром в центре окна
- output = "x=";
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2);
- double x;
- cin >> x; //считывание аргумента
- output = name + "(" + to_string(x) + ")=" + to_string(fun(x)); //подсчёт значения функции
- print(output, xMiddle - (int)output.length() / 2, HEIGHT / 2 + 1);
- int input = 0; //хранение последней нажатой клавиши
- while (input != 27 && input != 13) //выход в меню при нажатии esc или enter
- {
- input = _getch();
- }
- }
- //подсчёт сложных функций
- double sin_grad(double x)
- {
- return sin((x * PI) / 180);
- }
- double cos_grad(double x)
- {
- return cos((x * PI) / 180);
- }
- double tan_grad(double x)
- {
- return tan((x * PI) / 180);
- }
- double sqrt_double(double x)
- {
- return sqrt(x);
- }
- int main()
- {
- string resize = "mode " + to_string(WIDTH) + ", " + to_string(HEIGHT); //формирование строки для изменения размера консоли и отключения полосы прокрутки
- system(resize.c_str()); //выполнение системной команды для изменения размера консоли с предварительным преобразованием строки в C-style строку(требуется как аргумент в system)
- setlocale(LC_ALL, "Russian"); //включение русской кодировки
- //формирование цвета текста и фона консоли http://vsokovikov.narod.ru/New_MSDN_API/Console/scrbuf.htm#attrib_char_cons
- SetConsoleTextAttribute(hCon, BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); //изменение цвета текста и фона консоли
- menu complex_functions; //меню для сложных функций
- complex_functions.add("sin", bind(calc_complex, "sin", sin_grad));
- complex_functions.add("cos", bind(calc_complex, "cos", cos_grad));
- complex_functions.add("tg", bind(calc_complex, "tg", tan_grad));
- complex_functions.add("sqrt", bind(calc_complex, "sqrt", sqrt_double));
- menu main_menu;//главное меню
- main_menu.add("complex functions", bind(&menu::get, complex_functions)); //передача указателя на функцию часть класса
- main_menu.add("simple function", calck_simple);
- main_menu.add("exit", bind(exit,0)); //преобразование void (*)(int) в void(*)() с предопределением аргумента
- while (true) //запрет выхода по esc из главного меню
- main_menu.get();
- }
Advertisement
Add Comment
Please, Sign In to add comment