当前位置: 首页 > news >正文

Windows C++控制台菜单库开发与源码展示

Windows C++控制台菜单库

  • 声明:
  • 演示视频:
  • 一、前言
  • 二、具体框架
  • 三、源码展示
    • console_screen_set.h
    • frame
      • console_screen_frame_base.h
      • console_screen_frame_char.h
      • console_screen_frame_wchar_t.h
      • console_screen_frame.h
    • menu
      • console_screen_menu_base.h
      • console_screen_menu_operate.h
      • console_screen_menu.h
    • text
      • console_screen_text_base.h
      • console_screen_text.h
  • 四、代码参考

声明:

开发环境为 VS2022 C++,菜单库源码(2200行左右)为本人独立制作,转载使用请标明出处,谢谢!

演示视频:

C++菜单库例子展示

一、前言

做控制台菜单的时候总感觉太耗时了,因为坐标不对需要修改,还要一个一个检查,以及颜色的处理。

具体操作可看这篇博客C语言伪图形与键盘操作加扫雷实例(写的太挫了),所以我想制作一个控制台菜单库,便于在菜单方面的快速开发。

二、具体框架

在这里插入图片描述
因为制作的时候是走一步看一步,导致设计十分冗余,后续有时间可能会更新调整。这里我列举一些里面的功能:

  1. set 包含常用的函数,例如光标移动、隐藏等等。
  2. menu(模板) 包含选项、框架、内置键盘操作、内置鼠标操作、打印、清除等等。
  3. text(模板) 包含打印、清除等等。

在使用宽字符(wchar_t)对应的类,如:wmenu、wtext、应该加上这一句:

	std::wcout.imbue(std::locale("zh_CN"));		

详细可参考 C++基础(十八)区域设置、locale、中文乱码、中文不输出 ,这里不赘述。

三、源码展示

console_screen_set.h

#pragma once#include <CoreWindow.h>
#include <stdio.h>namespace my
{inline void SetPos(int x, int y){COORD pos = { x, y };SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);}inline void HideCursor(){CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);}inline void SetWordSize(int SizeX, int SizeY){CONSOLE_FONT_INFOEX font_infoex;COORD pos = { SizeX, SizeY };font_infoex.cbSize = sizeof(CONSOLE_FONT_INFOEX);font_infoex.dwFontSize = pos;SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), false, &font_infoex);}inline void FlushBuffer(){FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));}inline void SetScreenSize(short consoleWide, short consoleHigh){char cmd[100];sprintf_s(cmd, "mode con cols=%d lines=%d", consoleWide, consoleHigh);system(cmd);}inline void GetMouseOperate(){if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_EXTENDED_FLAGS | ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT)){fprintf(stderr, "%s\n", "SetConsoleMode");}}
}

frame

console_screen_frame_base.h

#pragma once#include <CoreWindow.h>
#include <cassert>namespace my
{template<class T>class console_screen_frame_base{template<class Type, class CH, class STRING>friend class console_screen_frame;template<class PFUNC, class MENU, class FRAME, class CHAR, class STRING>friend class console_screen_menu;template<class TEXTCHAR, class FRAME, class STRING, class CHAR>friend class console_screen_text;public:console_screen_frame_base(int x = 0, int y = 0, int high = 5, int wide = 10,T up = 0, T down = 0, T left = 0, T right = 0,T top_left = 0, T bottom_left = 0, T top_right = 0, T bottom_right = 0):_x(x), _y(y), _high(high), _wide(wide), _up(up), _down(down), _left(left), _right(right), _top_left(top_left), _bottom_left(bottom_left), _top_right(top_right), _bottom_right(bottom_right){assert(x >= 0 && y >= 0);assert(high >= 0 && wide >= 0);}void changePos(int x, int y){assert(x >= 0 && y >= 0);_x = x;_y = y;}void changeFrameSize(int high, int wide){assert(high >= 0 && wide >= 0);_high = high;_wide = wide;}void changeSide(T up = 0, T down = 0, T left = 0, T right = 0){_up = up == 0 ? _up : up;_down = down == 0 ? _down : down;_left = left == 0 ? _left : left;_right = right == 0 ? _right : right;}void changeCorner(T top_left = 0, T bottom_left = 0, T top_right = 0, T bottom_right = 0){_top_left = top_left == 0 ? _top_left : top_left;_bottom_left = bottom_left == 0 ? _bottom_left : bottom_left;_top_right = top_right == 0 ? _top_right : top_right;_bottom_right = bottom_right == 0 ? _bottom_right : bottom_right;}void changeUp(T up){_up = up;}void changeDown(T down){_down = down;}void changeLeft(T left){_left = left;}void changeRight(T right){_right = right;}void changeTopLeft(T top_left){_top_left = top_left;}void changeTopRight(T top_right){_top_right = top_right;}void changeBottomLeft(T bottom_left){_bottom_left = bottom_left;}void changeBottomRight(T bottom_right){_bottom_right = bottom_right;}protected:void printFrame(){if (_up != 0){printCharUp();}if (_down != 0){printCharDown();}if (_left != 0){printCharLeft();}if (_right != 0){printCharRight();}if (_top_left != 0 ||_top_right != 0 ||_bottom_left != 0 ||_bottom_right != 0){printCharCorner();}}virtual void printCharUp() = 0;virtual void printCharDown() = 0;virtual void printCharLeft() = 0;virtual void printCharRight() = 0;virtual void printCharCorner() = 0;void cleanFrame(){if (_up != 0){cleanCharUp();}if (_down != 0){cleanCharDown();}if (_left != 0){cleanCharLeft();}if (_right != 0){cleanCharRight();}if (_top_left != 0 ||_top_right != 0 ||_bottom_left != 0 ||_bottom_right != 0){cleanCharCorner();}}virtual void cleanCharUp() = 0;virtual void cleanCharDown() = 0;virtual void cleanCharLeft() = 0;virtual void cleanCharRight() = 0;virtual void cleanCharCorner() = 0;protected:short _x;short _y;short _high;short _wide;T _up;T _down;T _left;T _right;T _top_left = 0;T _bottom_left = 0;T _top_right = 0;T _bottom_right = 0;};
}

console_screen_frame_char.h

#pragma once#include "console_screen_frame_base.h"
#include "console_screen_set.h"
#include <iostream>namespace my
{extern void SetPos(int x, int y);class console_screen_frame_char : public console_screen_frame_base<signed char>{public:console_screen_frame_char(int x, int y, int high, int wide,signed char up = 0, signed char down = 0,signed char left = 0, signed char right = 0,signed char top_left = 0, signed char bottom_left = 0,signed char top_right = 0, signed char bottom_right = 0):console_screen_frame_base(x, y, high, wide, up, down, left, right,top_left, bottom_left, top_right, bottom_right){;}void show(){printFrame();}void clean(){cleanFrame();}protected:void printCharUp(){SetPos(_x + 1, _y);for (int wide = 1; wide <= _wide - 2; ++wide){std::cout << _up;}}void printCharDown(){SetPos(_x + 1, _y + _high - 1);for (int wide = 1; wide <= _wide - 2; ++wide){std::cout << _down;}}void printCharLeft(){for (int high = 1; high <= _high - 2; ++high){SetPos(_x, _y + high);std::cout << _left;}}void printCharRight(){for (int high = 1; high <= _high - 2; ++high){SetPos(_x + _wide - 1, _y + high);std::cout << _right;}}void printCharCorner(){SetPos(_x, _y);std::cout << _top_left;SetPos(_x + _wide - 1, _y);std::cout << _top_right;SetPos(_x, _y + _high - 1);std::cout << _bottom_left;SetPos(_x + _wide - 1, _y + _high - 1);std::cout << _bottom_right;}void cleanCharUp(){signed char temp = _up;_up = ' ';printCharUp();_up = temp;}void cleanCharDown(){signed char temp = _down;_down = ' ';printCharDown();_down = temp;}void cleanCharLeft(){signed char temp = _left;_left = ' ';printCharLeft();_left = temp;}void cleanCharRight(){signed char temp = _right;_right = ' ';printCharRight();_right = temp;}void cleanCharCorner(){signed char temp1 = _top_left;signed char temp2 = _bottom_left;signed char temp3 = _top_right;signed char temp4 = _bottom_right;changeCorner(' ', ' ', ' ', ' ');printCharCorner();changeCorner(temp1, temp2, temp3, temp4);}};
}

console_screen_frame_wchar_t.h

#pragma once#include "console_screen_frame_base.h"
#include "console_screen_set.h"
#include <iostream>namespace my
{class console_screen_frame_wchar_t : public console_screen_frame_base<wchar_t>{public:console_screen_frame_wchar_t(int x, int y, int high, int wide,wchar_t up = 0, wchar_t down = 0,wchar_t left = 0, wchar_t right = 0,wchar_t top_left = 0, wchar_t bottom_left = 0,wchar_t top_right = 0, wchar_t bottom_right = 0):console_screen_frame_base(x, y, high, wide, up, down, left, right,top_left, bottom_left, top_right, bottom_right){;}void show(){printFrame();}void clean(){cleanFrame();}protected:void printCharUp(){for (int wide = 0; wide <= _wide - 6; wide += 2){SetPos(_x + 2 + wide, _y);std::wcout << _up;}}void printCharDown(){for (int wide = 0; wide <= _wide - 6; wide += 2){SetPos(_x + 2 + wide, _y + _high - 1);std::wcout << _down;}}void printCharLeft(){for (int high = 1; high <= _high - 2; ++high){SetPos(_x, _y + high);std::wcout << _left;}}void printCharRight(){for (int high = 1; high <= _high - 2; ++high){SetPos(_x + _wide - 2, _y + high);std::wcout << _right;}}void printCharCorner(){SetPos(_x, _y);std::wcout << _top_left;SetPos(_x + _wide - 2, _y);std::wcout << _top_right;SetPos(_x, _y + _high - 1);std::wcout << _bottom_left;SetPos(_x + _wide - 2, _y + _high - 1);std::wcout << _bottom_right;}void cleanCharUp(){SetPos(_x + 2, _y);for (int wide = 0; wide <= _wide - 4; ++wide){std::cout << ' ';}}void cleanCharDown(){SetPos(_x + 2, _y + _high - 1);for (int wide = 0; wide <= _wide - 4; ++wide){std::cout << ' ';}}void cleanCharLeft(){for (int high = 1; high <= _high - 2; ++high){SetPos(_x, _y + high);std::cout << ' ' << ' ';}}void cleanCharRight(){for (int high = 1; high <= _high - 2; ++high){SetPos(_x + _wide - 2, _y + high);std::cout << ' ' << ' ';}}void cleanCharCorner(){SetPos(_x, _y);std::cout << ' ' << ' ';SetPos(_x + _wide - 2, _y);std::cout << ' ' << ' ';SetPos(_x, _y + _high - 1);std::cout << ' ' << ' ';SetPos(_x + _wide - 2, _y + _high - 1);std::cout << ' ' << ' ';}};
}

console_screen_frame.h

#pragma once#include "console_screen_frame_char.h"
#include "console_screen_frame_wchar_t.h"
#include <vector>
#include <utility>namespace my
{enum FRAME_DIRECTION{Up = 0,Down,Left,Right};template<class T, class CH, class STRING>class console_screen_frame{template<class PFUNC, class MENU, class FRAME, class CHAR, class STRING>friend class console_screen_menu;template<class TEXTCHAR, class FRAME, class STRING, class CHAR>friend class console_screen_text;public:console_screen_frame(int x, int y, int high, int wide,CH up = 0, CH down = 0, CH left = 0, CH right = 0,CH top_left = 0, CH bottom_left = 0, CH top_right = 0, CH bottom_right = 0):_the_char(x, y, high, wide, up, down, left, right, top_left, bottom_left, top_right, bottom_right){;}void setPos(int x, int y){_the_char.changePos(x, y);}void setFrameSize(int high, int wide){_the_char.changeFrameSize(high, wide);}void setSide(CH up = 0, CH down = 0, CH left = 0, CH right = 0){_the_char.changeSide(up, down, left, right);}void setCorner(CH top_left = 0, CH bottom_left = 0,CH top_right = 0, CH bottom_right = 0){_the_char.changeCorner(top_left, bottom_left, top_right, bottom_right);}void setUp(CH up){_the_char.changeUp(up);}void setDown(CH down){_the_char.changeDown(down);}void setLeft(CH left){_the_char.changeLeft(left);}void setRight(CH right){_the_char.changeRight(right);}void setTopLeft(CH top_left){_the_char.changeTopLeft(top_left);}void setTopRight(CH top_right){_the_char.changeTopRight(top_right);}void setBottomLeft(CH bottom_left){_the_char.changeBottomLeft(bottom_left);}void setBottomRight(CH bottom_right){_the_char.changeBottomRight(bottom_right);}void frameShow(){_the_char.show();if (sizeof(CH) == sizeof(signed char)){wordShow((void(*)(STRING))&getCout, (void(*)(CH))&getCoutC);}else{wordShow((void(*)(STRING))&getWcout, (void(*)(CH))&getWcoutC);}}void frameClean(){_the_char.clean();}void numWord(int number){_word.resize(number);_word_space.resize(number);}void setWord(int pos, STRING str1, signed char direction, short distance){assert(pos >= 0 && pos < _word.size());_word[pos] = str1;_word_space[pos] = { direction, distance };}void recallWord(int pos){assert(pos >= 0 && pos < _word.size());_word.erase(_word.begin() + pos);_word_space.erase(_word_space.begin() + pos);}protected:void wordShow(void(*outfuncString)(STRING), void(*outfuncChar)(CH)){for (int i = 0; i < _word.size(); ++i){if (_the_char._up != 0 && _word_space[i].first == Up){SetPos(_the_char._x + _word_space[i].second, _the_char._y);if (_word[i] == nullptr){continue;}outfuncString(_word[i]);}else if (_the_char._down != 0 && _word_space[i].first == Down){SetPos(_the_char._x + _word_space[i].second, _the_char._y + _the_char._high - 1);if (_word[i] == nullptr){continue;}outfuncString(_word[i]);}else if (_the_char._left != 0 && _word_space[i].first == Left){int len = clen(_word[i]);for (int j = 0; j < len; ++j){SetPos(_the_char._x, _the_char._y + _word_space[i].second + j);if (_word[i] == nullptr){continue;}outfuncChar(_word[i][j]);}}else if (_the_char._right != 0 && _word_space[i].first == Right){int len = clen(_word[i]);for (int j = 0; j < len; ++j){SetPos(_the_char._x + _the_char._wide - sizeof(CH), _the_char._y + _word_space[i].second + j);if (_word[i] == nullptr){continue;}outfuncChar(_word[i][j]);}}}}static void getWcout(STRING str1){std::wcout << str1;}static void getCout(STRING str1){std::cout << str1;}static void getWcoutC(CH ch){std::wcout << ch;}static void getCoutC(CH ch){std::cout << ch;}protected:std::vector<STRING> _word;								// 嵌入词std::vector<std::pair<signed char, short>> _word_space;	// 嵌入词位置T _the_char;typedef size_t(*p_T_char)(STRING);p_T_char clen = sizeof(CH) == sizeof(signed char) ? (p_T_char)&strlen : (p_T_char)&wcslen;};typedef console_screen_frame<console_screen_frame_char, signed char, const char*> frame;typedef console_screen_frame<console_screen_frame_wchar_t, wchar_t, const wchar_t*> wframe;}

menu

console_screen_menu_base.h

#pragma once#include "console_screen_set.h"
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
#include <Windows.h>
#include <utility>namespace my
{template<class T>static T Max(T a, T b){return a > b ? a : b;}typedef enum CONSOLE_SCREEN_COLOR{CBlack = 0,CBlue,CGreen,CLight_blue,CRed,CPurple,CYellow,CWhite,BBlack = 0,BBlue = 0x10,BGreen = 0x20,BLight_blue = 0x30,BRed = 0x40,BPurple = 0x50,BYellow = 0x60,BWhite = 0x70} the_color;class console_screen_menu_base{public:console_screen_menu_base(int x, int y, int rowNum = 1, int colNum = 1, int high = 1, int wide = 1):_x(x), _y(y), _high(high), _wide(wide), _rowNum(rowNum), _colNum(colNum), _option(rowNum, std::vector<std::string>(colNum, std::string("nullptr"))), _char_space(rowNum, std::vector<std::pair<short, short>>(colNum, { 1, 1 })), _char_color(rowNum, std::vector<std::pair<short, bool>>(colNum, { CWhite, 0 })), _background_space(rowNum, std::vector<std::pair<short, short>>(colNum, { 0, 0 })), _background_color(rowNum, std::vector<std::pair<short, bool>>(colNum, { BBlack, 0 })){assert(rowNum >= 1 && colNum >= 1);assert(x >= 0 && y >= 0);assert(high >= 0 && wide >= 0);}const std::string& getOption(int rowPos, int colPos){assert(rowPos >= 1 && colPos >= 1);return _option[rowPos - 1][colPos - 1];}void setOption(int rowPos, int colPos, const std::string& str1,short front = 1, short back = 1){assert(rowPos >= 1 && colPos >= 1);assert(front >= 0 && back >= 0);assert(rowPos <= _rowNum && colPos <= _colNum);_option[rowPos - 1][colPos - 1] = str1;_char_space[rowPos - 1][colPos - 1] = { front, back };}void setColor(int rowPos, int colPos, int charColor, bool charStrength, int backgroundColor = 0, bool backgroundStrength = false){char_color(rowPos, colPos, charColor, charStrength);background_color(rowPos, colPos, backgroundColor, backgroundStrength);}void setCharColor(int rowPos, int colPos, int colorNum, bool strength = false){char_color(rowPos, colPos, colorNum, strength);}void setBackgroundColor(int rowPos, int colPos, int colorNum, bool strength = false){background_color(rowPos, colPos, colorNum, strength);}void setCharSpace(int rowPos, int colPos, int front, int back){assert(rowPos >= 1 && colPos >= 1);_char_space[rowPos - 1][colPos - 1] = { front, back };}void setBackgroundSpace(int rowPos, int colPos, int front, int back){assert(rowPos >= 1 && colPos >= 1);_background_space[rowPos - 1][colPos - 1] = { front, back };}void setRowSpace(int row){assert(row >= 0);_row_space = row;}void setPos(int x, int y){assert(x >= 0 && y >= 0);_x = x;_y = y;}void show(){show_or_clean_ready(true);}void clean(){show_or_clean_ready(false);}protected:void char_color(int rowPos, int colPos, int colorNum, bool strength){assert(CBlack <= colorNum && colorNum <= CWhite);_char_color[rowPos - 1][colPos - 1] = { colorNum, strength };}void background_color(int rowPos, int colPos, int colorNum, bool strength){assert(BBlack <= colorNum && colorNum <= BWhite);_background_color[rowPos - 1][colPos - 1] = { colorNum, strength };}void clean_ready(int i, int j, int x, int y){int len1 = _option[i][j].size();if (_background_space[i][j].first > 0){len1 += _background_space[i][j].first;}if (_background_space[i][j].second > 0){len1 += _background_space[i][j].second;}// 补丁:正序打印会影响宽字体,逆向可解决for (int i = len1 - 1; i >= 0; --i){SetPos(x + i, y);std::cout << ' ';}}void show_ready(int i, int j){int charStrength = 0;int backgroundStrength = 0;if (_background_color[i][j].second == true){backgroundStrength = BACKGROUND_INTENSITY;}if (_char_color[i][j].second == true){charStrength = FOREGROUND_INTENSITY;}if (_background_space[i][j].first > 0){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), _background_color[i][j].first | backgroundStrength);std::cout << std::string(_background_space[i][j].first, ' ');}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), _char_color[i][j].first | charStrength | _background_color[i][j].first | backgroundStrength);std::cout << _option[i][j];if (_background_space[i][j].second > 0){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), _background_color[i][j].first | backgroundStrength);std::cout << std::string(_background_space[i][j].second, ' ');}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CWhite | BBlack);}void show_or_clean_ready(bool option){int countPosY = 0;for (int i = 0; i < _rowNum; ++i){if (i != 0){countPosY += _row_space;}int countPosX = 0;for (int j = 0; j < _colNum; ++j){int front = _char_space[i][j].first;if (j != 0){countPosX += _option[i][j - 1].size();countPosX += _char_space[i][j - 1].first + _background_space[i][j - 1].first;countPosX += _background_space[i][j - 1].second + _char_space[i][j - 1].second;}SetPos(_x + front + countPosX, _y + i + countPosY);if (option == true){show_ready(i, j);}else{clean_ready(i, j, _x + front + countPosX, _y + i + countPosY);}}}}protected:std::vector<std::vector<std::string>> _option;							// 选项//std::vector<std::vector<const char*>> _option;std::vector<std::vector<std::pair<short, short>>> _char_space;			// 字符间距std::vector<std::vector<std::pair<short, bool>>> _char_color;			// 字符 颜色 与 颜色加强std::vector<std::vector<std::pair<short, short>>> _background_space;	// 背景间距std::vector<std::vector<std::pair<short, bool>>> _background_color;		// 背景 颜色 与 颜色加强short _x;short _y;short _high;short _wide;//short _rowNum = 1;//short _colNum = 1;int _rowNum = 1;int _colNum = 1;signed char _row_space = 0;			// 行距};
}

console_screen_menu_operate.h

#pragma once#include "console_screen_set.h"
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
#include <Windows.h>
#include <utility>namespace my
{template<class T>static T Max(T a, T b){return a > b ? a : b;}typedef enum CONSOLE_SCREEN_COLOR{CBlack = 0,CBlue,CGreen,CLight_blue,CRed,CPurple,CYellow,CWhite,BBlack = 0,BBlue = 0x10,BGreen = 0x20,BLight_blue = 0x30,BRed = 0x40,BPurple = 0x50,BYellow = 0x60,BWhite = 0x70} the_color;class console_screen_menu_base{public:console_screen_menu_base(int x, int y, int rowNum = 1, int colNum = 1, int high = 1, int wide = 1):_x(x), _y(y), _high(high), _wide(wide), _rowNum(rowNum), _colNum(colNum), _option(rowNum, std::vector<std::string>(colNum, std::string("nullptr"))), _char_space(rowNum, std::vector<std::pair<short, short>>(colNum, { 1, 1 })), _char_color(rowNum, std::vector<std::pair<short, bool>>(colNum, { CWhite, 0 })), _background_space(rowNum, std::vector<std::pair<short, short>>(colNum, { 0, 0 })), _background_color(rowNum, std::vector<std::pair<short, bool>>(colNum, { BBlack, 0 })){assert(rowNum >= 1 && colNum >= 1);assert(x >= 0 && y >= 0);assert(high >= 0 && wide >= 0);}const std::string& getOption(int rowPos, int colPos){assert(rowPos >= 1 && colPos >= 1);return _option[rowPos - 1][colPos - 1];}void setOption(int rowPos, int colPos, const std::string& str1,short front = 1, short back = 1){assert(rowPos >= 1 && colPos >= 1);assert(front >= 0 && back >= 0);assert(rowPos <= _rowNum && colPos <= _colNum);_option[rowPos - 1][colPos - 1] = str1;_char_space[rowPos - 1][colPos - 1] = { front, back };}void setColor(int rowPos, int colPos, int charColor, bool charStrength, int backgroundColor = 0, bool backgroundStrength = false){char_color(rowPos, colPos, charColor, charStrength);background_color(rowPos, colPos, backgroundColor, backgroundStrength);}void setCharColor(int rowPos, int colPos, int colorNum, bool strength = false){char_color(rowPos, colPos, colorNum, strength);}void setBackgroundColor(int rowPos, int colPos, int colorNum, bool strength = false){background_color(rowPos, colPos, colorNum, strength);}void setCharSpace(int rowPos, int colPos, int front, int back){assert(rowPos >= 1 && colPos >= 1);_char_space[rowPos - 1][colPos - 1] = { front, back };}void setBackgroundSpace(int rowPos, int colPos, int front, int back){assert(rowPos >= 1 && colPos >= 1);_background_space[rowPos - 1][colPos - 1] = { front, back };}void setRowSpace(int row){assert(row >= 0);_row_space = row;}void setPos(int x, int y){assert(x >= 0 && y >= 0);_x = x;_y = y;}void show(){show_or_clean_ready(true);}void clean(){show_or_clean_ready(false);}protected:void char_color(int rowPos, int colPos, int colorNum, bool strength){assert(CBlack <= colorNum && colorNum <= CWhite);_char_color[rowPos - 1][colPos - 1] = { colorNum, strength };}void background_color(int rowPos, int colPos, int colorNum, bool strength){assert(BBlack <= colorNum && colorNum <= BWhite);_background_color[rowPos - 1][colPos - 1] = { colorNum, strength };}void clean_ready(int i, int j, int x, int y){int len1 = _option[i][j].size();if (_background_space[i][j].first > 0){len1 += _background_space[i][j].first;}if (_background_space[i][j].second > 0){len1 += _background_space[i][j].second;}// 补丁:正序打印会影响宽字体,逆向可解决for (int i = len1 - 1; i >= 0; --i){SetPos(x + i, y);std::cout << ' ';}}void show_ready(int i, int j){int charStrength = 0;int backgroundStrength = 0;if (_background_color[i][j].second == true){backgroundStrength = BACKGROUND_INTENSITY;}if (_char_color[i][j].second == true){charStrength = FOREGROUND_INTENSITY;}if (_background_space[i][j].first > 0){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), _background_color[i][j].first | backgroundStrength);std::cout << std::string(_background_space[i][j].first, ' ');}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), _char_color[i][j].first | charStrength | _background_color[i][j].first | backgroundStrength);std::cout << _option[i][j];if (_background_space[i][j].second > 0){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), _background_color[i][j].first | backgroundStrength);std::cout << std::string(_background_space[i][j].second, ' ');}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CWhite | BBlack);}void show_or_clean_ready(bool option){int countPosY = 0;for (int i = 0; i < _rowNum; ++i){if (i != 0){countPosY += _row_space;}int countPosX = 0;for (int j = 0; j < _colNum; ++j){int front = _char_space[i][j].first;if (j != 0){countPosX += _option[i][j - 1].size();countPosX += _char_space[i][j - 1].first + _background_space[i][j - 1].first;countPosX += _background_space[i][j - 1].second + _char_space[i][j - 1].second;}SetPos(_x + front + countPosX, _y + i + countPosY);if (option == true){show_ready(i, j);}else{clean_ready(i, j, _x + front + countPosX, _y + i + countPosY);}}}}protected:std::vector<std::vector<std::string>> _option;							// 选项//std::vector<std::vector<const char*>> _option;std::vector<std::vector<std::pair<short, short>>> _char_space;			// 字符间距std::vector<std::vector<std::pair<short, bool>>> _char_color;			// 字符 颜色 与 颜色加强std::vector<std::vector<std::pair<short, short>>> _background_space;	// 背景间距std::vector<std::vector<std::pair<short, bool>>> _background_color;		// 背景 颜色 与 颜色加强short _x;short _y;short _high;short _wide;//short _rowNum = 1;//short _colNum = 1;int _rowNum = 1;int _colNum = 1;signed char _row_space = 0;			// 行距};
}

console_screen_menu.h

#pragma once#include "console_screen_frame.h"
#include "console_screen_menu_operate.h"namespace my
{typedef enum console_screen_menu_operate_way{keyboard = 1,mouse,} way;template<class PFUNC = int(*)(),class MENU = console_screen_menu_operate<PFUNC>, class FRAME = frame, class CHAR = signed char, class STRING = const char*>class console_screen_menu{public:console_screen_menu(int x = 0, int y = 0, int high = 10, int wide = 20, int rowNum = 1, int colNum = 1, bool operate_switch = false):_frame(x, y, high, wide),_menu(x, y, operate_switch, rowNum, colNum, high, wide){;}public:	// 自定义操作准备template<class T1, class T2, class T3, class T4>int operateCustom(int (*customize)(T1&, T2&, T3&, T4&), T2& fun1, T3& fun2, T4& fun3){return customize(*this, fun1, fun2, fun3);}template<class T1, class T2, class T3>int operateCustom(int (*customize)(T1&, T2&, T3&), T2& fun1, T3& fun2){return customize(*this, fun1, fun2);}template<class T1, class T2>int operateCustom(int (*customize)(T1&, T2&), T2& fun1){return customize(*this, fun1);}template<class T>int operateCustom(int (*customize)(T&)){return customize(*this);}void customSetMenuCharColor(int rowPos, int colPos, int colorNum, bool strength = false){_menu.setCharColor(rowPos, colPos, colorNum, strength);}const std::string& customGetMenuOption(int rowPos, int colPos){return _menu.getOption(rowPos, colPos);}void customSetMenuOption(int rowPos, int colPos, const std::string& str1, short front = 0, short back = 0){setMenuOption(rowPos, colPos, str1, front, back);}void customMouseAndOptionAc(int posX, int posY){_menu.mouseAndOptionAc(posX, posY);}THE_POS customGetMouseCheckAlgorithm(int mouseX, int mouseY){return _menu.mouseAndOptionDockingAlgorithm(mouseX, mouseY);}void customGetMouseOperate(){_menu.getMouseOperate();}void customOperateClean(){_menu.operateClean();}int customGetSleepTime(){return _menu._sleep_time;}PFUNC customGetOptionButton(int cursorX, int cursorY){assert(cursorX >= 0 && cursorX < _menu._colNum);assert(cursorY >= 0 && cursorY < _menu._rowNum);return _menu._the_way[cursorY][cursorX];}int customGetCursorColNum(){return _menu._colNum;}int customGetCursorX(){return _menu._cursorPosX;}void customSetCursorX(int cursorX){_menu.cursorXReset(cursorX);}int customGetCursorRowNum(){return _menu._rowNum;}int customGetCursorY(){return _menu._cursorPosY;}//short customGetOptionRowNum()//{//	return _menu._rowNum;//}//short customGetOptionY()//{//	return _menu._cursorPosY;//}void customSetCursorY(int cursorY){_menu.cursorYReset(cursorY);}void customSetCursorPos(int cursorX, int cursorY){_menu.cursorReset(cursorX, cursorY);}void customOperateShow(){_menu.operateShow();}bool customMenuCheckOperate(){return _menu._open_operate;}public:	// 静态准备void staticInit(bool yes = true){_staticInit = yes;}bool alreadyStaticInit(){return _staticInit;}public:	// 有关菜单与框架void setPosCompare(short x, short y){assert(x >= 0);assert(y >= 0);_compare_x = x;_compare_y = y;_menu.setPos(_menu._x + x, _menu._y + y);}void setAndCheckPos(int x, int y){_frame.setPos(x, y);_menu.setPos(x, y);checkPosFrameWithMenu();}void show(){_menu.show();_frame.frameShow();}void clean(){_menu.clean();_frame.frameClean();}public:	// 只关于菜单的void setMaxSpaceOper(){_menu.setMaxSpaceOper();}void setSameSpaceOperWithBack(){_menu.setSameSpaceOperWithBack();}void setMenuButton(int rowPos, int colPos, PFUNC customize){_menu.setWay(rowPos, colPos, customize);}void setOperateSpace(int rowPos, int colPos, int front, int back){_menu.setOperateSapce(rowPos, colPos, front, back);}void setOperateColor(int rowPos, int colPos, int colorNum, bool strength = false){_menu.setOperateColor(rowPos, colPos, colorNum, strength);}void operateMode(bool Yes = false){_menu.operateMode(Yes);}int operateWay(int way, int optionX = 1, int optionY = 1){int info = 0;if (way == keyboard){info = _menu.operateKeyboardStart(optionX, optionY);}else if (way == mouse){info = _menu.operateMouseStart();}return info;}//void operateMouseStart()//{//	_menu.operateMouseStart();//}//void operateKeyboardStart(int posX = 0, int posY = 0)//{//	_menu.operateKeyboardStart(posX, posY);//}void setMenuRowSpace(int row){_menu.setRowSpace(row);}void setMenuBackgroundSpace(int rowPos, int colPos, int front, int back){_menu.setBackgroundSpace(rowPos, colPos, front, back);}void setMenuCharSpace(int rowPos, int colPos, int front, int back){_menu.setCharSpace(rowPos, colPos, front, back);}void setMenuBackgroundColor(int rowPos, int colPos, int colorNum, int strength = false){_menu.setBackgroundColor(rowPos, colPos, colorNum, strength);}void setMenuCharColor(int rowPos, int colPos, int colorNum, int strength = false){_menu.setCharColor(rowPos, colPos, colorNum, strength);}void setMenuColor(int rowPos, int colPos, int charColor, bool charStrength, int backgroundColor = 0, bool backgroundStrength = false){_menu.setColor(rowPos, colPos, charColor, charStrength, backgroundColor, backgroundStrength);}void setMenuOption(int rowPos, int colPos, const std::string& str1, short front = 1, short back = 1){_menu.setOption(rowPos, colPos, str1, front, back);}public:	// 只关于框架的void setFrameSide(CHAR up, CHAR down, CHAR left , CHAR right){_frame.setSide(up, down, left, right);checkPosFrameWithMenu();}void setFrameCorner(CHAR top_left, CHAR bottom_left, CHAR top_right, CHAR bottom_right){_frame.setCorner(top_left, bottom_left, top_right, bottom_right);checkPosFrameWithMenu();}void setFrameNumWord(int number){_frame.numWord(number);}void setFrameWord(int pos, STRING str1, signed char direction, short distance){_frame.setWord(pos, str1, direction, distance);}void setFrameRecallWord(int pos){_frame.recallWord(pos);}protected:void checkPosFrameWithMenu(){if (_frame._the_char._x != _menu._x && _frame._the_char._y != _menu._y){return;}short up = 0;short down = 0;short left = 0;short right = 0;if (_frame._the_char._up != 0){up = 1;}if (_frame._the_char._left != 0){left = sizeof(CHAR);}if (_frame._the_char._down != 0){down = 1;}if (_frame._the_char._right != 0){right = 1;}_menu.setPos(_frame._the_char._x + left + _compare_x, _frame._the_char._y + up + _compare_y);}protected:FRAME _frame;MENU _menu;short _compare_x = 0;short _compare_y = 0;bool _staticInit = false;};typedef console_screen_menu<int(*)(), console_screen_menu_operate<int(*)()>, frame, signed char, const char*> menu;typedef console_screen_menu<int(*)(), console_screen_menu_operate<int(*)()>, wframe, wchar_t, const wchar_t*> wmenu;
}

text

console_screen_text_base.h

#pragma once#include <vector>
#include <utility>
#include <cassert>
#include <iostream>namespace my
{template<class STRING, class CH>class console_screen_text_base{template<class TEXTCHAR, class FRAME, class STRING, class CHAR>friend class console_screen_text;public:console_screen_text_base(short x, short y, short high = 10, short wide = 10, int textNum = 1):_text_num(textNum, std::pair<STRING, short>(nullptr, 0)),_x(x),_y(y),_high(high),_wide(wide){assert(textNum > 0);assert(high > 0 && wide > 0);assert(x >= 0 && y >= 0);}void setText(int theTextRank, STRING theText, short frontDistance){assert(theTextRank > 0);assert(theText != nullptr && frontDistance >= 0);_text_num[theTextRank - 1] = { theText, frontDistance };}void setRowSpace(int row){assert(row >= 0);_row_space = row;}void setHideAndWide(int high, int wide){assert(high > 0 && wide > 0);_high = high;_wide = wide;}void showNoCheck(){if (sizeof(CH) == sizeof(signed char)){textShowClean((void(*)(STRING))&getCout, true);}else{textShowClean((void(*)(STRING)) & getWcout, true);}}void cleanNoCheck(){if (sizeof(CH) == sizeof(signed char)){textShowClean((void(*)(STRING)) & getCout, false);}else{textShowClean((void(*)(STRING)) & getWcout, false);}}void cleanAndCheck(){if (sizeof(CH) == sizeof(signed char)){textShowCleanAndCheck((void(*)(CH)) & getCoutC, false);}else{textShowCleanAndCheck((void(*)(CH)) & getWcoutC, false);}}void showAndCheck(){if (sizeof(CH) == sizeof(signed char)){textShowCleanAndCheck((void(*)(CH)) & getCoutC, true);}else{textShowCleanAndCheck((void(*)(CH)) & getWcoutC, true);}}void setPos(short x, short y){assert(x >= 0 && y >= 0);_x = x;_y = y;}protected://文本长度受宽度限制,过长会换行void textShowCleanAndCheck(void(*outfuncString)(CH), bool isShow){int countPosY = 0;int wideLine = _wide;if (sizeof(CH) == 2){wideLine /= 2;}for (int i = 0; i < _text_num.size(); ++i){if (i != 0){countPosY += _row_space;}if (_text_num[i].first == nullptr){return;}int len = theStrlen(_text_num[i].first);int j = 0;int printIndex = 0;if (sizeof(CH) == 1){printIndex = _text_num[i].second;}else{printIndex = _text_num[i].second % 2;printIndex = _text_num[i].second / 2;}SetPos(_x + _text_num[i].second, _y + i + countPosY);while (j < wideLine - printIndex){if (isShow == true){outfuncString(_text_num[i].first[j]);}else{CH blank = 0;if (sizeof(CH) == 2){blank = L' ';outfuncString(blank);outfuncString(blank);}else{blank = ' ';outfuncString(blank);}}++j;}++countPosY;while (printIndex < len){SetPos(_x, _y + i + countPosY);printIndex = j;int maxSize = wideLine + printIndex;if (maxSize > len){maxSize = len;}while (j < maxSize){if (isShow == true){outfuncString(_text_num[i].first[j]);}else{CH blank = 0;if (sizeof(CH) == 2){blank = L' ';outfuncString(blank);outfuncString(blank);}else{blank = ' ';outfuncString(blank);}}++j;}if (j < len){++countPosY;}}}}void textShowClean(void(*outfuncString)(STRING), bool isShow){int countPosY = 0;for (int i = 0; i < _text_num.size(); ++i){if (i != 0){countPosY += _row_space;}SetPos(_x + _text_num[i].second, _y + i + countPosY);if (_text_num[i].first == nullptr){return;}if (isShow == true){outfuncString(_text_num[i].first);}else{int len = theStrlen(_text_num[i].first);if (sizeof(CH) == 1){std::cout << std::string(len, ' ');}else{std::wcout << std::wstring(len * 2, L' ');}}}}static void getWcout(STRING str1){std::wcout << str1;}static void getCout(STRING str1){std::cout << str1;}static void getWcoutC(CH ch){std::wcout << ch;}static void getCoutC(CH ch){std::cout << ch;}protected:std::vector<std::pair<STRING, short>> _text_num;	// 文本存储short _row_space = 0;								// 行距short _x;short _y;short _high;short _wide;	typedef size_t(*p_T_char)(STRING);p_T_char theStrlen = sizeof(CH) == sizeof(signed char) ? (p_T_char)&strlen : (p_T_char)&wcslen;};typedef console_screen_text_base<const char*, signed char> text_base;typedef console_screen_text_base<const wchar_t*, wchar_t> wtext_base;}

console_screen_text.h

#pragma once#include "console_screen_frame.h"
#include "console_screen_text_base.h"namespace my
{template<class TEXTCHAR, class FRAME, class STRING, class CHAR>class console_screen_text{public:console_screen_text(short x, short y, short high = 10, short wide = 20, int textNum = 1):_text(x, y, high, wide, textNum), _frame(x, y, high, wide){;}public:	// 静态准备void staticInit(bool yes = true){_staticInit = yes;}bool alreadyStaticInit(){return _staticInit;}public:	// 有关文本与框架void setPosCompare(short x, short y){assert(x >= 0);assert(y >= 0);_compare_x = x;_compare_y = y;setTextPos(_text._x + x, _text._y + y);}void checkPosFrameWithText(){if (_frame._the_char._x != _text._x && _frame._the_char._y != _text._y){return;}short up = 0;short down = 0;short left = 0;short right = 0;if (_frame._the_char._up != 0){up = 1;}if (_frame._the_char._left != 0){left = sizeof(CHAR);}if (_frame._the_char._down != 0){down = 1;}if (_frame._the_char._right != 0){right = 1;}setTextPos(_frame._the_char._x + left + _compare_x, _frame._the_char._y + up + _compare_y);_text._high = _frame._the_char._high - up * 2;_text._wide = _frame._the_char._wide - left * 2;}void setAndCheckPos(int x, int y){_frame.setPos(x, y);_text.setPos(x, y);checkPosFrameWithText();}void show(){_frame.frameShow();_text.showNoCheck();}void showAndCheck(){_frame.frameShow();_text.showAndCheck();}void clean(){_frame.frameClean();_text.cleanNoCheck();}void cleanAndCheck(){_frame.frameClean();_text.cleanAndCheck();}public:	// 只关于文本的void setTextPos(short x, short y){_text.setPos(x, y);}//void showAndCheck()//{//	_text.showAndCheck();//}//void showButNoCheck()//{//	_text.showButNoCheck();//}void setHideAndWide(int high, int wide){_text.setRowSpace(high, wide);}void setRowSpace(int row){_text.setRowSpace(row);}void setText(int theTextRank, STRING text, short frontDistance){_text.setText(theTextRank, text, frontDistance);}public:	// 只关于框架的void setFrameSide(CHAR up, CHAR down, CHAR left, CHAR right){_frame.setSide(up, down, left, right);checkPosFrameWithText();}void setFrameCorner(CHAR top_left, CHAR bottom_left, CHAR top_right, CHAR bottom_right){_frame.setCorner(top_left, bottom_left, top_right, bottom_right);checkPosFrameWithText();}void setFrameNumWord(int number){_frame.numWord(number);}void setFrameWord(int pos, STRING str1, signed char direction, short distance){_frame.setWord(pos, str1, direction, distance);}void setFrameRecallWord(int pos){_frame.recallWord(pos);}protected:TEXTCHAR _text;FRAME _frame;short _compare_x = 0;short _compare_y = 0;bool _staticInit = false;};typedef console_screen_text<text_base, frame, const char*, signed char> text;typedef console_screen_text<wtext_base, wframe, const wchar_t*, wchar_t> wtext;}

四、代码参考

后续可能会出一份使用菜单库的博客,这里只给一个菜单供大家参考。

#include "console_screen_menu.h"
#include <iostream>int isQuit()
{return 1;
}int main()
{std::wcout.imbue(std::locale("zh_CN"));my::HideCursor();static my::wmenu isATest(2, 1, 5, 10, 2, 1, true);if (isATest.alreadyStaticInit() == false){isATest.setMenuOption(1, 1, "开始", 0, 0);isATest.setMenuOption(2, 1, "结束", 0, 0);isATest.setFrameSide(L'□', L'■', L'○', L'●');isATest.setFrameCorner(L'△', L'▲', L'▽', L'▼');isATest.setMenuBackgroundSpace(1, 1, 0, 2);isATest.setMenuBackgroundSpace(2, 1, 0, 2);isATest.setOperateSpace(1, 1, 2, 0);isATest.setOperateSpace(2, 1, 2, 0);isATest.setMenuButton(2, 1, isQuit);isATest.staticInit(true);}int operWay = 1;isATest.show();if (operWay == 1){isATest.operateWay(my::keyboard);}else{isATest.operateWay(my::mouse);}return 0;
}

相关文章:

Windows C++控制台菜单库开发与源码展示

Windows C控制台菜单库 声明&#xff1a;演示视频&#xff1a;一、前言二、具体框架三、源码展示console_screen_set.hframeconsole_screen_frame_base.hconsole_screen_frame_char.hconsole_screen_frame_wchar_t.hconsole_screen_frame.h menuconsole_screen_menu_base.hcons…...

ARM——驱动——Linux启动流程和Linux启动

一、flash存储器 lash存储器&#xff0c;全称为Flash EEPROM Memory&#xff0c;又名闪存&#xff0c;是一种长寿命的非易失性存储器。它能够在断电情况下保持所存储的数据信息&#xff0c;因此非常适合用于存储需要持久保存的数据。Flash存储器的数据删除不是以单个的字节为单…...

Docker和虚拟机的区别详细讲解

Docker 和虚拟机&#xff08;VM&#xff09;是现代 IT 基础设施中常见的技术&#xff0c;它们都用于在单一硬件上运行多个操作环境&#xff0c;但它们的工作原理、性能、资源利用和使用场景存在显著差异。以下是对 Docker 和虚拟机区别的详细讲解。 一、基础概念 1. Docker …...

leetcode_68. 文本左右对齐

68. 文本左右对齐 题目描述&#xff1a;给定一个单词数组 words 和一个长度 maxWidth &#xff0c;重新排版单词&#xff0c;使其成为每行恰好有 maxWidth 个字符&#xff0c;且左右两端对齐的文本。 你应该使用 “贪心算法” 来放置给定的单词&#xff1b;也就是说&#xff0c…...

python探索分形和混沌

简单产生复杂&#xff0c;混沌孕育秩序 0. 引言 a. 分形 fractal 【也叫碎形】 分形是一种具有自相似性和复杂结构的几何图形。在分形结构中&#xff0c;无论放大多少次&#xff0c;局部的结构特征都与整体结构相似。这种特性在自然界中广泛存在&#xff0c;比如树木枝干、山…...

LeetCode77 组合

前言 题目&#xff1a; 77. 组合 文档&#xff1a; 代码随想录——组合 编程语言&#xff1a; C 解题状态&#xff1a; 没尝试出来 思路 经典的组合问题&#xff0c;可以考虑使用回溯法。使用回溯法时可以根据回溯法的模板来考虑如何解决。 代码 回溯法 class Solution { p…...

C#:Bitmap类使用方法—第1讲

首先看一下Bitmap定义&#xff1a;封装 GDI 位图&#xff0c;此位图由图形图像及其属性的像素数据组成。 Bitmap 是用于处理由像素数据定义的图像的对象。 下面介绍一下使用的例子&#xff1a; Bitmap image1; private void Button1_Click(System.Object sender, System.Eve…...

PaddleNLP 3.0 支持大语言模型开发

huggingface不支持模型并行。张量并行&#xff0c;不满足大规模预训练的需求。 1、组网部分 2、数据流 3、训练器 4、异步高效的模型存储...

32次8.21(学习playbook-roles,脚本创建数据库和表,mycat读写分离)

1.roles目录介绍 files&#xff1a;⽤来存放由copy模块或script模块调⽤的⽂件。 tasks&#xff1a;⾄少有⼀个main.yml⽂件&#xff0c;定义各tasks。 handlers:有⼀个main.yml⽂件&#xff0c;定义各handlers。 templates&#xff1a;⽤来存放jinjia2模板。 vars&#xff1a…...

I2C通信协议(软件I2C和硬件I2C)

相比于之前学的异步全双工且需要两条通信线的串口通信&#xff0c;I2C则为同步半双工&#xff0c;仅需要一条通信线&#xff0c;全双工与半双工区别如下&#xff1a; 全双工&#xff08;Full Duplex&#xff09;半双工&#xff08;Half Duplex&#xff09;数据传输方式同时双向…...

Linux入门——08 进程间通讯——管道

1.进程间通讯 1.1什么是通讯 进程具有独立性&#xff08;每个进程都有自己的PCB,独立地址空间&#xff0c;页表&#xff09;但是要进行进程的通信&#xff0c;通信的成本一定不低&#xff0c;打破了独立性 进程间通信目的 数据传输&#xff1a;一个进程需要将它的数据发送给…...

深入探讨SD NAND的SD模式与SPI模式初始化

在嵌入式系统和存储解决方案中&#xff0c;SD NAND的广泛应用是显而易见的。CS创世推出的SD NAND支持SD模式和SPI模式&#xff0c;这两种模式在功能和实现上各有优劣。在本文中&#xff0c;我们将深入探讨这两种模式的初始化过程&#xff0c;并比较它们在不同应用场景下的优劣&…...

【jvm】栈和堆的区别

目录 1. 用途2. 线程共享性3. 内存分配和回收4. 生命周期5. 性能特点 1. 用途 1.堆&#xff1a;主要用于存储对象实例和数组。在Java中&#xff0c;所有通过new关键字创建的对象都会被分配到堆上。堆是一个大的内存池&#xff0c;用于存储所有的Java对象&#xff0c;包括实例变…...

智能的意义是降低世界的不确定性

世界充满着不确定性&#xff0c;而智能天生就追求一定的确定性&#xff0c;因为不确定性会危及智能的生存。智能本身是一种有序、相对确定的结构产生的&#xff0c;虽然也有一定的不确定性&#xff0c;而且这些不确定性有利于智能的进化&#xff0c;但是&#xff0c;相对而言&a…...

python实现指数平滑法进行时间序列预测

python实现指数平滑法进行时间序列预测 一、指数平滑法定义 1、指数平滑法是一种常用的时间序列预测算法,有一次、二次和三次平滑,通过加权系数来调整历史数据权重; 2、主要思想是:预测值是以前观测值的加权和,且对不同的数据给予不同的权数,新数据给予较大的权数,旧数…...

linux文件——用户缓冲区——概念深度探索、IO模拟实现

前言&#xff1a;本篇文章主要讲解文件缓冲区。 讲解的方式是通过抛出问题&#xff0c; 然后通过分析问题&#xff0c; 将缓冲区的概念与原理一步一步地讲解。同时&#xff0c; 本节内容在最后一部分还会带友友们模拟实现一下c语言的printf&#xff0c; fprintf接口&#xff0c…...

Hive3:常用查询语句整理

一、数据准备 建库 CREATE DATABASE itheima; USE itheima;订单表元数据 1 1000000 100058 6 -1 509.52 0.00 28155.40 499.33 0 0 lisi shanghai 157 2019-06-22 17:28:15 2019-06-22 17:28:15 1 2 5000000 100061 72 -1 503.86 0.00 38548.00 503.86 1 0 zhangsan shangha…...

Ubuntu下载安装教程|Ubuntu最新长期支持(LTS)版本24.04 LTS下载安装

安装Ubuntu Ubuntu最新长期支持(LTS)版本24.04 LTS Ubuntu 24.04 LTS | 概览 Ubuntu长期支持(LTS)版本&#xff0c;LTS意为“长期支持”&#xff0c;一般为5年。LTS版本将提供免费安全和维护更新至 2029年4月。 Ubuntu 24.04 LTS&#xff08;代号“Noble Numbat”&#xff0c;…...

通知:《自然语言及语音处理设计开发工程师》即将开课!

自然语言及语音处理设计开发工程师&#xff1a;未来职业的黄金选择 下面我们来看看证书颁发的背景&#xff1a;​ 为进一步贯彻落实中共中央印发《关于深化人才发展体制机制改革的意见》和国务院印发《关于“十四五”数字经济发展规划》等有关工作的部署要求&#xff0c;深入实…...

Vim youcompleteme Windows 安装保姆级教程

不说废话。 准备 检查 Vim 的 Python 配置 安装好 vim 和 python 后&#xff08;python 必须 ≥ \ge ≥ 3.6&#xff09;&#xff0c;在 cmd 下运行 vim --version会弹出以下窗口。 如果发现 python/dyn 和 python3/dyn 都是 - &#xff08;我不知道只有前者是 能不能运行…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

[QMT量化交易小白入门]-六十二、ETF轮动中简单的评分算法如何获取历史年化收益32.7%

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。 QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。 文章目录 相关阅读1. 策略概述2. 趋势评分模块3 代码解析4 木头…...

Qt学习及使用_第1部分_认识Qt---Qt开发基本流程

前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...

CMake系统学习笔记

CMake系统学习笔记 基础操作 最基本的案例 // code #include <iostream>int main() {std::cout << "hello world " << std::endl;return 0; }// CMakeLists.txt cmake_minimum_required(VERSION 3.0)# 定义当前工程名称 project(demo)add_execu…...

【Redis】Redis 的持久化策略

目录 一、RDB 定期备份 1.2 触发方式 1.2.1 手动触发 1.2.2.1 自动触发 RDB 持久化机制的场景 1.2.2.2 检查是否触发 1.2.2.3 线上运维配置 1.3 检索工具 1.4 RDB 备份实现原理 1.5 禁用 RDB 快照 1.6 RDB 优缺点分析 二、AOF 实时备份 2.1 配置文件解析 2.2 开启…...