├── TODO.md ├── .gitignore ├── example ├── 04_delay_operations.cpp ├── 01_basic_output.cpp ├── 06_cursor_control.cpp ├── 03_font_styles.cpp ├── 05_progress_bar.cpp ├── 07_terminal_size.cpp ├── 09_typewriter_effect.cpp ├── 13_file_loading_progress.cpp ├── 17_guess_number_game.cpp ├── 12_system_info.cpp ├── 18_game_menu.cpp ├── 11_animation_effects.cpp ├── 10_color_menu.cpp ├── 14_color_logger.cpp ├── 08_key_wait.cpp ├── 20_terminal_printer_demo.cpp ├── 15_interactive_cli.cpp ├── 02_color_output.cpp ├── 19_painting_game.cpp └── 16_snake_game.cpp ├── .github └── FUNDING.yml ├── LICENSE ├── .vscode └── settings.json ├── doc ├── basic_ansi_code.md ├── ansi_code_reference.md ├── os_support.md ├── tc_quick_start.md ├── tc_terminal_functions.md ├── tc_functionality.md ├── tc_updated_functionality.md ├── tc_key_handling.md ├── tc_color_functions.md └── tc_api_reference.md ├── include ├── tc_progress.hpp ├── tc.hpp ├── tc_print.hpp ├── tc_stream.hpp ├── tc_wait.hpp ├── tc_terminal.hpp └── tc_system_utils.hpp └── README.md /TODO.md: -------------------------------------------------------------------------------- 1 | # TC.hpp后续更新计划 2 | 3 | - [ ] 便捷颜色函数添加多参数,返回整体字符串 4 | - [ ] Hash/SHA256值计算 5 | - [ ] Base16/32/64/128编码和解码 6 | - [ ] 文件读取、权限更改 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Temp folders 35 | ./test 36 | ./codebuddy -------------------------------------------------------------------------------- /example/04_delay_operations.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | 3 | int main() { 4 | // 基本延时 5 | tc::println("等待1秒..."); 6 | tc::wait(1.0); 7 | tc::println("等待完成"); 8 | 9 | // 毫秒延时 10 | tc::println("等待500毫秒..."); 11 | tc::tsleep(500).execute(); 12 | tc::println("等待完成"); 13 | 14 | // 流式延时 15 | tc::tout << "开始" << tc::tsleep(300) << "中间" << tc::tsleep(300) << "结束" << std::endl; 16 | 17 | // 延时流 18 | tc::println("延时流开始"); 19 | tc::tsleep_stream << 800; 20 | tc::println("延时流结束"); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /example/01_basic_output.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | 3 | int main() { 4 | // 标准输出 5 | tc::print("Hello", " ", "World"); // 输出: Hello World 6 | tc::println("Hello", " ", "World"); // 输出: Hello World 并换行 7 | 8 | // 打印不同类型的值 9 | tc::println("整数: ", 42); 10 | tc::println("浮点数: ", 3.14159); 11 | tc::println("布尔值: ", true); 12 | 13 | // 链式输出 14 | tc::print().print("链式").print(" ").println("输出"); 15 | 16 | // 流式输出 17 | tc::tout << "流式输出" << std::endl; 18 | tc::tout << "支持多种类型: " << 42 << ", " << 3.14 << std::endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /example/06_cursor_control.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | 3 | int main() { 4 | // 清屏 5 | tc::printer().clear(); 6 | 7 | // 移动光标 8 | tc::printer().moveCursor(10, 5); 9 | tc::println("在位置(10,5)打印"); 10 | 11 | tc::printer().moveCursor(15, 10); 12 | tc::println("在位置(15,10)打印"); 13 | 14 | // 相对移动 15 | tc::printer().moveCursor(tc::Printer::Direction::Up, 2); 16 | tc::println("上移2行"); 17 | 18 | tc::printer().moveCursor(tc::Printer::Direction::Right, 5); 19 | tc::println("右移5列"); 20 | 21 | // 隐藏/显示光标 22 | tc::println("\n\n光标将在3秒内隐藏..."); 23 | tc::printer().hideCursor(); 24 | tc::wait(3.0); 25 | tc::printer().showCursor(); 26 | tc::println("光标已显示"); 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /example/03_font_styles.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | 3 | int main() { 4 | // 基本样式 5 | tc::println(TFONT_BOLD, "粗体文本", TFONT_RESET); 6 | tc::println(TFONT_UNDERLINE, "下划线文本", TFONT_RESET); 7 | tc::println(TFONT_ITALIC, "斜体文本", TFONT_RESET); 8 | tc::println(TFONT_CROSSED, "删除线文本", TFONT_RESET); 9 | tc::println(TFONT_REVERSE, "反色文本", TFONT_RESET); 10 | 11 | // 组合样式 12 | tc::println(TFONT_BOLD, TFONT_UNDERLINE, "粗体下划线文本", TFONT_RESET); 13 | tc::println(TFONT_ITALIC, TFONT_CROSSED, "斜体删除线文本", TFONT_RESET); 14 | 15 | // 样式与颜色组合 16 | tc::println(TCOLOR_RED, TFONT_BOLD, "红色粗体文本", TCOLOR_RESET); 17 | tc::println(TCOLOR_BLUE, TFONT_UNDERLINE, "蓝色下划线文本", TCOLOR_RESET); 18 | tc::println(TCOLOR_GREEN, BCOLOR_YELLOW, TFONT_BOLD, "绿字黄底粗体", TCOLOR_RESET); 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /example/05_progress_bar.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | 3 | int main() { 4 | // 基本进度条 5 | tc::ProgressBar bar1(30, "#", "-", TCOLOR_GREEN); 6 | for (int i = 0; i <= 100; ++i) { 7 | bar1.show(i / 100.0, "处理中..."); 8 | tc::wait(0.02); 9 | } 10 | bar1.finish("完成!"); 11 | 12 | // 自定义进度条 13 | tc::println("\n自定义进度条:"); 14 | tc::ProgressBar bar2(40, "█", "░", TCOLOR_CYAN); 15 | for (int i = 0; i <= 100; ++i) { 16 | bar2.show(i / 100.0, "加载中..."); 17 | tc::wait(0.01); 18 | } 19 | bar2.finish("加载完成!"); 20 | 21 | // 模拟文件下载进度条 22 | tc::println("\n模拟下载:"); 23 | tc::ProgressBar bar3(50, "▓", "▒", TCOLOR_BLUE); 24 | for (int i = 0; i <= 100; ++i) { 25 | bar3.show(i / 100.0, "下载中... " + std::to_string(i) + "%"); 26 | tc::wait(0.03); 27 | } 28 | bar3.finish("下载完成!"); 29 | 30 | return 0; 31 | } -------------------------------------------------------------------------------- /example/07_terminal_size.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | 3 | int main() { 4 | // 获取终端尺寸 5 | auto size = tc::printer().getSize(); 6 | tc::println("终端大小: ", size.first, "x", size.second); 7 | 8 | // 在终端中央打印文本 9 | int centerX = size.first / 2; 10 | int centerY = size.second / 2; 11 | 12 | tc::printer().moveCursor(centerX - 10, centerY); 13 | tc::println(TCOLOR_GREEN, "这是终端的中央位置", TCOLOR_RESET); 14 | 15 | // 在四个角落打印 16 | tc::printer().moveCursor(1, 1); 17 | tc::println(TCOLOR_RED, "左上角", TCOLOR_RESET); 18 | 19 | tc::printer().moveCursor(size.first - 6, 1); 20 | tc::println(TCOLOR_BLUE, "右上角", TCOLOR_RESET); 21 | 22 | tc::printer().moveCursor(1, size.second - 1); 23 | tc::println(TCOLOR_YELLOW, "左下角", TCOLOR_RESET); 24 | 25 | tc::printer().moveCursor(size.first - 6, size.second - 1); 26 | tc::println(TCOLOR_MAGENTA, "右下角", TCOLOR_RESET); 27 | 28 | // 在中间位置等待按键 29 | tc::printer().moveCursor(centerX - 10, centerY + 2); 30 | tc::println("按任意键继续..."); 31 | tc::waitKey(); 32 | 33 | return 0; 34 | } -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | custom: ['https://afdian.tv/a/Sean537/plan', 'https://p.clash.ink/i/2025/07/30/sny9yw.jpg', 'https://p.clash.ink/i/2025/07/30/snybef.jpg'] 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Sean537 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /example/09_typewriter_effect.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | 4 | void typewriter(const std::string& text, int delay_ms = 50) { 5 | for (char c : text) { 6 | tc::print(c); 7 | std::cout.flush(); // 立即刷新输出 8 | tc::wait(delay_ms / 1000.0); // 将毫秒转换为秒 9 | } 10 | tc::println(); 11 | std::cout.flush(); 12 | } 13 | 14 | int main() { 15 | // 基本打字机效果 16 | typewriter("这是一个打字机效果的演示..."); 17 | 18 | // 彩色打字机效果 19 | tc::print(TCOLOR_GREEN); 20 | typewriter("这是绿色的打字机效果...", 70); 21 | tc::print(TCOLOR_RESET); 22 | 23 | // 带样式的打字机效果 24 | tc::print(TCOLOR_YELLOW, TFONT_BOLD); 25 | typewriter("这是黄色粗体的打字机效果...", 30); 26 | tc::print(TCOLOR_RESET); 27 | 28 | // 变速打字机效果 29 | tc::print(TCOLOR_CYAN); 30 | std::string text = "这是变速的打字机效果..."; 31 | for (char c : text) { 32 | tc::print(c); 33 | std::cout.flush(); // 立即刷新输出 34 | int delay = (c == ' ' || c == '.') ? 200 : 40; 35 | tc::wait(delay / 1000.0); // 将毫秒转换为秒 36 | } 37 | tc::println(); 38 | tc::print(TCOLOR_RESET); 39 | std::cout.flush(); 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /example/13_file_loading_progress.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void simulateFileLoading(const std::string& filename, int fileSize) { 8 | tc::println(TCOLOR_CYAN, "开始加载文件: ", filename, TCOLOR_RESET); 9 | 10 | tc::ProgressBar bar(40, "█", "░", TCOLOR_GREEN); 11 | 12 | // 模拟文件加载 13 | int loadedSize = 0; 14 | while (loadedSize < fileSize) { 15 | // 模拟加载一部分 16 | int chunk = std::min(fileSize / 50 + rand() % 100, fileSize - loadedSize); 17 | loadedSize += chunk; 18 | 19 | // 更新进度条 20 | double progress = static_cast(loadedSize) / fileSize; 21 | std::string msg = "加载中... " + std::to_string(loadedSize) + "/" + std::to_string(fileSize) + " 字节"; 22 | bar.show(progress, msg); 23 | 24 | // 模拟加载延迟 25 | tc::wait(0.05); 26 | } 27 | 28 | bar.finish("文件加载完成!"); 29 | } 30 | 31 | int main() { 32 | std::vector> files = { 33 | {"document.txt", 1024 * 10}, // 10 KB 34 | {"image.jpg", 1024 * 1024 * 2}, // 2 MB 35 | {"video.mp4", 1024 * 1024 * 15} // 15 MB 36 | }; 37 | 38 | for (const auto& file : files) { 39 | simulateFileLoading(file.first, file.second); 40 | tc::println(); 41 | } 42 | 43 | tc::println(TCOLOR_GREEN, TFONT_BOLD, "所有文件加载完成!", TCOLOR_RESET); 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /example/17_guess_number_game.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | 4 | int main() { 5 | tc::printer().clear(); 6 | tc::println(TCOLOR_CYAN, TFONT_BOLD, "猜数字游戏", TCOLOR_RESET); 7 | tc::println(TCOLOR_CYAN, "==========", TCOLOR_RESET); 8 | tc::println(); 9 | 10 | std::random_device rd; 11 | std::mt19937 gen(rd()); 12 | std::uniform_int_distribution<> distrib(1, 100); 13 | 14 | int secretNumber = distrib(gen); 15 | int guess; 16 | int attempts = 0; 17 | 18 | tc::println("我想了一个1到100之间的数字。"); 19 | 20 | while (true) { 21 | tc::print(TCOLOR_GREEN, "请猜一个数字: ", TCOLOR_RESET); 22 | std::cin >> guess; 23 | 24 | if (std::cin.fail()) { 25 | std::cin.clear(); 26 | std::cin.ignore(10000, '\n'); 27 | tc::println(TCOLOR_RED, "请输入一个有效的数字!", TCOLOR_RESET); 28 | continue; 29 | } 30 | 31 | attempts++; 32 | 33 | if (guess < secretNumber) { 34 | tc::println(TCOLOR_BLUE, "太小了! 再试一次。", TCOLOR_RESET); 35 | } else if (guess > secretNumber) { 36 | tc::println(TCOLOR_YELLOW, "太大了! 再试一次。", TCOLOR_RESET); 37 | } else { 38 | tc::println(); 39 | tc::println(TCOLOR_GREEN, TFONT_BOLD, "恭喜! 你猜对了!", TCOLOR_RESET); 40 | tc::println("秘密数字是: ", secretNumber); 41 | tc::println("你用了 ", attempts, " 次尝试。"); 42 | break; 43 | } 44 | } 45 | 46 | tc::println(); 47 | tc::println("按任意键退出..."); 48 | tc::waitKey(); 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /example/12_system_info.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | 4 | int main() { 5 | // 获取系统信息 6 | int osCode = tc::systemCheck(); 7 | const char* osName = tc::getOSName(osCode); 8 | std::string osVersionInfo = tc::getOSVersionInfo(); 9 | 10 | // 获取当前时间 11 | int year = tc::getSystemTime(SYS_YEAR); 12 | int month = tc::getSystemTime(SYS_MONTH); 13 | int day = tc::getSystemTime(SYS_DAY); 14 | int hour = tc::getSystemTime(SYS_HOUR); 15 | int minute = tc::getSystemTime(SYS_MINUTE); 16 | int second = tc::getSystemTime(SYS_SECOND); 17 | int timestamp = tc::getSystemTime(); 18 | 19 | // 获取终端尺寸 20 | auto termSize = tc::printer().getSize(); 21 | 22 | // 显示系统信息 23 | tc::println(TCOLOR_CYAN, TFONT_BOLD, "系统信息", TCOLOR_RESET); 24 | tc::println(TCOLOR_CYAN, "=========", TCOLOR_RESET); 25 | 26 | tc::println(TCOLOR_YELLOW, "操作系统: ", TCOLOR_RESET, osName, " (代码: ", osCode, "版本信息:", osVersionInfo, ")"); 27 | tc::println(TCOLOR_YELLOW, "当前时间: ", TCOLOR_RESET, 28 | year, "-", month < 10 ? "0" : "", month, "-", day < 10 ? "0" : "", day, " ", 29 | hour < 10 ? "0" : "", hour, ":", minute < 10 ? "0" : "", minute, ":", second < 10 ? "0" : "", second); 30 | tc::println(TCOLOR_YELLOW, "Unix时间戳: ", TCOLOR_RESET, timestamp); 31 | tc::println(TCOLOR_YELLOW, "终端尺寸: ", TCOLOR_RESET, termSize.first, "x", termSize.second); 32 | 33 | // 执行系统命令 34 | tc::println("\n", TCOLOR_CYAN, TFONT_BOLD, "系统命令输出", TCOLOR_RESET); 35 | tc::println(TCOLOR_CYAN, "===========", TCOLOR_RESET); 36 | 37 | #ifdef _WIN32 38 | tc::systemConsoleW(L"echo 当前目录内容:"); 39 | tc::systemConsole("dir"); 40 | #else 41 | tc::systemConsole("echo 当前目录内容:"); 42 | tc::systemConsole("ls -la"); 43 | #endif 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "atomic": "cpp", 4 | "bit": "cpp", 5 | "cctype": "cpp", 6 | "charconv": "cpp", 7 | "chrono": "cpp", 8 | "clocale": "cpp", 9 | "cmath": "cpp", 10 | "compare": "cpp", 11 | "concepts": "cpp", 12 | "cstddef": "cpp", 13 | "cstdint": "cpp", 14 | "cstdio": "cpp", 15 | "cstdlib": "cpp", 16 | "cstring": "cpp", 17 | "ctime": "cpp", 18 | "cwchar": "cpp", 19 | "deque": "cpp", 20 | "exception": "cpp", 21 | "format": "cpp", 22 | "forward_list": "cpp", 23 | "functional": "cpp", 24 | "initializer_list": "cpp", 25 | "iomanip": "cpp", 26 | "ios": "cpp", 27 | "iosfwd": "cpp", 28 | "iostream": "cpp", 29 | "istream": "cpp", 30 | "iterator": "cpp", 31 | "limits": "cpp", 32 | "list": "cpp", 33 | "locale": "cpp", 34 | "memory": "cpp", 35 | "new": "cpp", 36 | "optional": "cpp", 37 | "ostream": "cpp", 38 | "ratio": "cpp", 39 | "sstream": "cpp", 40 | "stack": "cpp", 41 | "stdexcept": "cpp", 42 | "stop_token": "cpp", 43 | "streambuf": "cpp", 44 | "string": "cpp", 45 | "system_error": "cpp", 46 | "thread": "cpp", 47 | "tuple": "cpp", 48 | "type_traits": "cpp", 49 | "typeinfo": "cpp", 50 | "unordered_map": "cpp", 51 | "utility": "cpp", 52 | "vector": "cpp", 53 | "xfacet": "cpp", 54 | "xhash": "cpp", 55 | "xiosbase": "cpp", 56 | "xlocale": "cpp", 57 | "xlocbuf": "cpp", 58 | "xlocinfo": "cpp", 59 | "xlocmes": "cpp", 60 | "xlocmon": "cpp", 61 | "xlocnum": "cpp", 62 | "xloctime": "cpp", 63 | "xmemory": "cpp", 64 | "xstring": "cpp", 65 | "xtr1common": "cpp", 66 | "xutility": "cpp" 67 | } 68 | } -------------------------------------------------------------------------------- /example/18_game_menu.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | #include 4 | 5 | // 注意:这个示例需要包含其他游戏示例的代码才能完整运行 6 | // 这里只展示菜单部分的实现 7 | 8 | int main() { 9 | tc::printer().clear(); 10 | 11 | std::vector gameOptions = { 12 | "贪吃蛇", 13 | "猜数字" 14 | }; 15 | 16 | int choice; 17 | do { 18 | tc::printer().clear(); 19 | tc::println(TCOLOR_CYAN, TFONT_BOLD, "TC.hpp 游戏示例", TCOLOR_RESET); 20 | tc::println(TCOLOR_CYAN, "==============", TCOLOR_RESET); 21 | tc::println(); 22 | 23 | tc::println(TCOLOR_YELLOW, "[1] ", TCOLOR_RESET, "贪吃蛇"); 24 | tc::println(TCOLOR_YELLOW, "[2] ", TCOLOR_RESET, "猜数字"); 25 | tc::println(); 26 | tc::println(TCOLOR_YELLOW, "[0] ", TCOLOR_RESET, "退出"); 27 | tc::println(); 28 | 29 | tc::print(TCOLOR_GREEN, "请选择游戏 (0-2): ", TCOLOR_RESET); 30 | std::cin >> choice; 31 | 32 | if (std::cin.fail()) { 33 | std::cin.clear(); 34 | std::cin.ignore(10000, '\n'); 35 | choice = -1; 36 | continue; 37 | } 38 | 39 | std::cin.ignore(10000, '\n'); // 清除输入缓冲区 40 | 41 | switch (choice) { 42 | case 1: 43 | tc::println(TCOLOR_GREEN, "启动贪吃蛇游戏...", TCOLOR_RESET); 44 | tc::println("(实际应用中,这里会调用贪吃蛇游戏的代码)"); 45 | tc::println("\n按任意键返回菜单..."); 46 | tc::waitKey(); 47 | break; 48 | case 2: 49 | tc::println(TCOLOR_GREEN, "启动猜数字游戏...", TCOLOR_RESET); 50 | tc::println("(实际应用中,这里会调用猜数字游戏的代码)"); 51 | tc::println("\n按任意键返回菜单..."); 52 | tc::waitKey(); 53 | break; 54 | case 0: 55 | tc::println(TCOLOR_GREEN, "谢谢使用!", TCOLOR_RESET); 56 | break; 57 | default: 58 | tc::println(TCOLOR_RED, "无效选择,请重试。", TCOLOR_RESET); 59 | tc::waitKey(); 60 | } 61 | } while (choice != 0); 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /example/11_animation_effects.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifndef _WIN32 9 | #include 10 | #include 11 | #endif 12 | 13 | void showSpinner(int seconds) { 14 | std::vector frames = {"|", "/", "-", "\\"}; 15 | int totalFrames = seconds * 10; 16 | 17 | auto& printer = tc::printer().hideCursor(); 18 | tc::terminal::flush(); // 确保光标隐藏立即生效 19 | 20 | for (int i = 0; i < totalFrames; ++i) { 21 | printer.print("\r", TCOLOR_CYAN, "加载中 ", frames[i % frames.size()], TCOLOR_RESET); 22 | tc::terminal::flush(); 23 | tc::wait(0.1); 24 | } 25 | 26 | printer.print("\r", TCOLOR_GREEN, "加载完成! ", TCOLOR_RESET) 27 | .println() 28 | .showCursor() 29 | .flush(); 30 | } 31 | 32 | void showBounce(int seconds) { 33 | std::string ball = "o"; 34 | std::string empty = " "; 35 | int width = 20; 36 | int totalFrames = seconds * 20; 37 | int pos = 0; 38 | int dir = 1; 39 | 40 | auto& printer = tc::printer().hideCursor(); 41 | tc::terminal::flush(); // 确保光标隐藏立即生效 42 | 43 | for (int i = 0; i < totalFrames; ++i) { 44 | printer.print("\r["); 45 | for (int j = 0; j < width; ++j) { 46 | if (j == pos) { 47 | printer.print(TCOLOR_RED, ball, TCOLOR_RESET); 48 | } else { 49 | printer.print(empty); 50 | } 51 | } 52 | printer.print("]"); 53 | tc::terminal::flush(); // 使用新的全局刷新函数 54 | 55 | pos += dir; 56 | if (pos == width - 1 || pos == 0) { 57 | dir = -dir; 58 | } 59 | 60 | tc::wait(0.05); 61 | } 62 | 63 | printer.println() 64 | .println(TCOLOR_GREEN, "动画结束!", TCOLOR_RESET) 65 | .showCursor(); 66 | tc::terminal::flush(); // 确保所有更改立即生效 67 | } 68 | 69 | int main() { 70 | tc::println("旋转加载动画:"); 71 | showSpinner(3); 72 | 73 | tc::println("\n弹跳球动画:"); 74 | showBounce(5); 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /doc/basic_ansi_code.md: -------------------------------------------------------------------------------- 1 | # ANSI 转义码参考手册 2 | 3 | ANSI转义码用于控制终端文本样式、颜色和光标位置。本文档提供完整的参考和实用示例。 4 | 5 | ## 目录 6 | - [文本样式](#文本样式) 7 | - [颜色控制](#颜色控制) 8 | - [光标控制](#光标控制) 9 | - [特殊效果](#特殊效果) 10 | - [使用注意事项](#使用注意事项) 11 | 12 | ## 文本样式 13 | 14 | | 转义码 | 功能描述 | 示例 | 兼容性说明 | 15 | |--------------|--------------------------|-------------------------------|--------------------------------| 16 | | `\033[0m` | 重置所有样式 | `echo -e "正常\033[1m加粗\033[0m"` | 所有主流终端支持 | 17 | | `\033[1m` | 加粗文本 | `\033[1m加粗文本\033[0m` | 广泛支持 | 18 | | `\033[3m` | 斜体文本 | `\033[3m斜体\033[0m` | 部分终端不支持(如Windows CMD)| 19 | | `\033[4m` | 下划线文本 | `\033[4m下划线\033[0m` | 广泛支持 | 20 | | `\033[7m` | 反色显示 | `\033[7m反色\033[0m` | 部分终端支持 | 21 | | `\033[9m` | 删除线文本 | `\033[9m删除线\033[0m` | 部分终端支持 | 22 | 23 | ## 颜色控制 24 | 25 | ### 基础8色 26 | | 前景码 | 背景码 | 颜色 | 示例 | 27 | |--------------|--------------|--------|-------------------------------| 28 | | `\033[30m` | `\033[40m` | 黑色 | `\033[30m黑字\033[0m` | 29 | | `\033[31m` | `\033[41m` | 红色 | `\033[31;41m红字红底\033[0m` | 30 | 31 | ### 256色扩展 32 | ```bash 33 | # 前景色示例 (橙色调) 34 | echo -e "\033[38;5;202m橙色文字\033[0m" 35 | 36 | # 背景色示例 37 | echo -e "\033[48;5;123m天蓝背景\033[0m" 38 | ``` 39 | 40 | ### RGB真彩色 41 | ```bash 42 | # 自定义前景色 (RGB) 43 | echo -e "\033[38;2;255;100;0m橙红色\033[0m" 44 | 45 | # 自定义背景色 46 | echo -e "\033[48;2;50;200;100m薄荷绿背景\033[0m" 47 | ``` 48 | 49 | ## 光标控制 50 | 51 | | 转义码 | 功能描述 | 示例 | 52 | |-----------------|------------------------|---------------------| 53 | | `\033[A` | 光标上移n行 | `\033[2A` 上移2行 | 54 | | `\033[B` | 光标下移n行 | `\033[1B` 下移1行 | 55 | | `\033[<行>;<列>H` | 移动光标到指定位置 | `\033[10;5H` 第10行第5列 | 56 | 57 | ## 特殊效果 58 | 59 | | 转义码 | 功能描述 | 兼容性说明 | 60 | |--------------|------------------------|--------------------| 61 | | `\033[8m` | 隐藏文本(安全输入用) | 部分终端支持 | 62 | | `\033[?25l` | 隐藏光标 | 需终端支持 | 63 | | `\033[?25h` | 显示光标 | 需终端支持 | 64 | 65 | ## 使用注意事项 66 | 67 | 1. **转义序列**:在bash中使用`-e`参数解释转义符,如`echo -e` 68 | 2. **兼容性测试**:重要功能应在目标终端测试 69 | 3. **重置样式**:使用`\033[0m`结束样式避免影响后续输出 70 | 4. **组合使用**:可组合多个代码,如`\033[1;31;43m`表示加粗红字黄底 71 | 72 | ```bash 73 | # 综合示例:彩色进度条 74 | for i in {1..10}; do 75 | echo -ne "\033[42m \033[0m" 76 | sleep 0.1 77 | done 78 | echo 79 | ``` 80 | 81 | > 提示:在支持真彩色的终端(如iTerm2、VS Code终端)可获得最佳视觉效果 82 | -------------------------------------------------------------------------------- /example/10_color_menu.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef _WIN32 7 | #include 8 | #include 9 | #endif 10 | 11 | int showMenu(const std::vector& options, const std::string& title = "菜单") { 12 | tc::printer().clear(); 13 | 14 | // 显示标题 15 | tc::println(TCOLOR_CYAN, TFONT_BOLD, title, TCOLOR_RESET); 16 | tc::println(TCOLOR_CYAN, std::string(title.length(), '='), TCOLOR_RESET); 17 | tc::println(); 18 | 19 | // 显示选项 20 | for (size_t i = 0; i < options.size(); ++i) { 21 | tc::println(TCOLOR_YELLOW, "[", i + 1, "] ", TCOLOR_RESET, options[i]); 22 | } 23 | 24 | tc::println(); 25 | tc::println(TCOLOR_YELLOW, "[0] ", TCOLOR_RESET, "退出"); 26 | tc::println(); 27 | 28 | // 获取用户输入 29 | int choice = -1; 30 | std::string input; 31 | 32 | while (true) { 33 | tc::print(TCOLOR_GREEN, "请选择 (0-", options.size(), "): ", TCOLOR_RESET); 34 | std::cout.flush(); // 确保提示立即显示 35 | 36 | std::getline(std::cin, input); 37 | 38 | // 转换输入为数字 39 | try { 40 | if (input.empty()) { 41 | continue; 42 | } 43 | choice = std::stoi(input); 44 | if (choice >= 0 && choice <= static_cast(options.size())) { 45 | break; 46 | } 47 | } catch (...) { 48 | choice = -1; 49 | } 50 | } 51 | 52 | return choice; 53 | } 54 | 55 | int main() { 56 | // 设置输入模式 57 | #ifndef _WIN32 58 | termios oldt, newt; 59 | tcgetattr(STDIN_FILENO, &oldt); 60 | newt = oldt; 61 | newt.c_lflag &= ~ICANON; 62 | newt.c_lflag &= ~ECHO; 63 | #endif 64 | 65 | std::vector mainOptions = { 66 | "选项一", 67 | "选项二", 68 | "选项三", 69 | "选项四" 70 | }; 71 | 72 | int choice; 73 | do { 74 | choice = showMenu(mainOptions, "彩色菜单示例"); 75 | 76 | tc::printer().clear(); 77 | switch (choice) { 78 | case 1: 79 | tc::println(TCOLOR_GREEN, "您选择了选项一", TCOLOR_RESET); 80 | break; 81 | case 2: 82 | tc::println(TCOLOR_BLUE, "您选择了选项二", TCOLOR_RESET); 83 | break; 84 | case 3: 85 | tc::println(TCOLOR_MAGENTA, "您选择了选项三", TCOLOR_RESET); 86 | break; 87 | case 4: 88 | tc::println(TCOLOR_YELLOW, "您选择了选项四", TCOLOR_RESET); 89 | break; 90 | case 0: 91 | tc::println(TCOLOR_RED, "退出程序", TCOLOR_RESET); 92 | break; 93 | } 94 | 95 | if (choice != 0) { 96 | tc::println("\n按任意键返回菜单..."); 97 | tc::waitKey(); 98 | } 99 | } while (choice != 0); 100 | 101 | #ifndef _WIN32 102 | // 恢复终端设置 103 | tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 104 | #endif 105 | 106 | return 0; 107 | } -------------------------------------------------------------------------------- /example/14_color_logger.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | enum class LogLevel { 7 | DEBUG, 8 | INFO, 9 | WARNING, 10 | ERR, // 改名以避免与Windows宏冲突 11 | CRITICAL 12 | }; 13 | 14 | class Logger { 15 | private: 16 | LogLevel minLevel_; 17 | 18 | std::string getCurrentTime() { 19 | std::stringstream ss; 20 | int hour = tc::getSystemTime(SYS_HOUR); 21 | int minute = tc::getSystemTime(SYS_MINUTE); 22 | int second = tc::getSystemTime(SYS_SECOND); 23 | 24 | ss << std::setfill('0') << std::setw(2) << hour << ":" 25 | << std::setfill('0') << std::setw(2) << minute << ":" 26 | << std::setfill('0') << std::setw(2) << second; 27 | 28 | return ss.str(); 29 | } 30 | 31 | public: 32 | Logger(LogLevel minLevel = LogLevel::DEBUG) : minLevel_(minLevel) {} 33 | 34 | void setLevel(LogLevel level) { 35 | minLevel_ = level; 36 | } 37 | 38 | template 39 | void debug(Args&&... args) { 40 | if (minLevel_ <= LogLevel::DEBUG) { 41 | tc::print(TCOLOR_CYAN, "[DEBUG] ", TCOLOR_RESET); 42 | tc::print("[", getCurrentTime(), "] "); 43 | tc::println(std::forward(args)...); 44 | } 45 | } 46 | 47 | template 48 | void info(Args&&... args) { 49 | if (minLevel_ <= LogLevel::INFO) { 50 | tc::print(TCOLOR_GREEN, "[INFO] ", TCOLOR_RESET); 51 | tc::print("[", getCurrentTime(), "] "); 52 | tc::println(std::forward(args)...); 53 | } 54 | } 55 | 56 | template 57 | void warning(Args&&... args) { 58 | if (minLevel_ <= LogLevel::WARNING) { 59 | tc::print(TCOLOR_YELLOW, "[WARNING] ", TCOLOR_RESET); 60 | tc::print("[", getCurrentTime(), "] "); 61 | tc::println(std::forward(args)...); 62 | } 63 | } 64 | 65 | template 66 | void error(Args&&... args) { 67 | if (minLevel_ <= LogLevel::ERR) { 68 | tc::print(TCOLOR_RED, "[ERROR] ", TCOLOR_RESET); 69 | tc::print("[", getCurrentTime(), "] "); 70 | tc::println(std::forward(args)...); 71 | } 72 | } 73 | 74 | template 75 | void critical(Args&&... args) { 76 | if (minLevel_ <= LogLevel::CRITICAL) { 77 | tc::print(TCOLOR_RED, TFONT_BOLD, "[CRITICAL]", TCOLOR_RESET, " "); 78 | tc::print("[", getCurrentTime(), "] "); 79 | tc::println(std::forward(args)...); 80 | } 81 | } 82 | }; 83 | 84 | int main() { 85 | Logger logger; 86 | 87 | logger.debug("这是一条调试信息"); 88 | logger.info("系统初始化完成"); 89 | logger.warning("磁盘空间不足"); 90 | logger.error("无法连接到数据库"); 91 | logger.critical("系统崩溃,无法恢复"); 92 | 93 | tc::println("\n设置日志级别为 WARNING:"); 94 | logger.setLevel(LogLevel::WARNING); 95 | 96 | logger.debug("这条调试信息不会显示"); 97 | logger.info("这条信息不会显示"); 98 | logger.warning("这条警告会显示"); 99 | logger.error("这条错误会显示"); 100 | logger.critical("这条严重错误会显示"); 101 | 102 | return 0; 103 | } -------------------------------------------------------------------------------- /example/08_key_wait.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | #include 4 | 5 | int main() { 6 | std::cout << "按键等待测试\n"; 7 | std::cout << "=============\n\n"; 8 | 9 | std::cout << "按任意键继续...\n"; 10 | tc::waitKey(); 11 | std::cout << "继续执行\n\n"; 12 | 13 | std::cout << "按 'A' 键继续...\n"; 14 | tc::waitKey('A'); 15 | std::cout << "检测到 'A' 键\n\n"; 16 | 17 | // 基本控制键测试 18 | std::cout << "按 ESC 键继续...\n"; 19 | tc::waitKey(KEY_ESC); 20 | std::cout << "检测到 ESC 键\n\n"; 21 | 22 | std::cout << "按空格键继续...\n"; 23 | tc::waitKey(KEY_SPACE); 24 | std::cout << "检测到空格键\n\n"; 25 | 26 | std::cout << "按回车键继续...\n"; 27 | tc::waitKey(KEY_ENTER); 28 | std::cout << "检测到回车键\n\n"; 29 | 30 | std::cout << "按Tab键继续...\n"; 31 | tc::waitKey(KEY_TAB); 32 | std::cout << "检测到Tab键\n\n"; 33 | 34 | std::cout << "按Backspace键继续...\n"; 35 | tc::waitKey(KEY_BACKSPACE); 36 | std::cout << "检测到Backspace键\n\n"; 37 | 38 | // 编辑键测试 39 | std::cout << "按Insert键继续...\n"; 40 | tc::waitKey(KEY_INSERT); 41 | std::cout << "检测到Insert键\n\n"; 42 | 43 | std::cout << "按Delete键继续...\n"; 44 | tc::waitKey(KEY_DELETE); 45 | std::cout << "检测到Delete键\n\n"; 46 | 47 | std::cout << "按Home键继续...\n"; 48 | tc::waitKey(KEY_HOME); 49 | std::cout << "检测到Home键\n\n"; 50 | 51 | std::cout << "按End键继续...\n"; 52 | tc::waitKey(KEY_END); 53 | std::cout << "检测到End键\n\n"; 54 | 55 | std::cout << "按Page Up键继续...\n"; 56 | tc::waitKey(KEY_PAGEUP); 57 | std::cout << "检测到Page Up键\n\n"; 58 | 59 | std::cout << "按Page Down键继续...\n"; 60 | tc::waitKey(KEY_PAGEDOWN); 61 | std::cout << "检测到Page Down键\n\n"; 62 | 63 | // 方向键测试 64 | std::cout << "按方向键测试:\n"; 65 | std::cout << "按上方向键...\n"; 66 | tc::waitKey(KEY_UP); 67 | std::cout << "检测到上方向键\n\n"; 68 | 69 | std::cout << "按下方向键...\n"; 70 | tc::waitKey(KEY_DOWN); 71 | std::cout << "检测到下方向键\n\n"; 72 | 73 | std::cout << "按左方向键...\n"; 74 | tc::waitKey(KEY_LEFT); 75 | std::cout << "检测到左方向键\n\n"; 76 | 77 | std::cout << "按右方向键...\n"; 78 | tc::waitKey(KEY_RIGHT); 79 | std::cout << "检测到右方向键\n\n"; 80 | 81 | // 功能键测试 82 | 83 | // 可能会触发开发环境的帮助窗口 84 | /* 85 | std::cout << "按F1键继续...\n"; 86 | tc::waitKey(KEY_F1); 87 | std::cout << "检测到F1键\n\n"; 88 | */ 89 | 90 | std::cout << "按F2键继续...\n"; 91 | tc::waitKey(KEY_F2); 92 | std::cout << "检测到F2键\n\n"; 93 | 94 | // 可能会触发控制台搜索功能 95 | /* 96 | std::cout << "按F3键继续...\n"; 97 | tc::waitKey(KEY_F3); 98 | std::cout << "检测到F3键\n\n"; 99 | */ 100 | 101 | std::cout << "按F4键继续...\n"; 102 | tc::waitKey(KEY_F4); 103 | std::cout << "检测到F4键\n\n"; 104 | 105 | // 可能会触发VS Code的调试窗口 106 | /* 107 | std::cout << "按F5键继续...\n"; 108 | tc::waitKey(KEY_F5); 109 | std::cout << "检测到F5键\n\n"; 110 | */ 111 | 112 | std::cout << "按F6键继续...\n"; 113 | tc::waitKey(KEY_F6); 114 | std::cout << "检测到F6键\n\n"; 115 | 116 | std::cout << "按F7键继续...\n"; 117 | tc::waitKey(KEY_F7); 118 | std::cout << "检测到F7键\n\n"; 119 | 120 | std::cout << "按F8键继续...\n"; 121 | tc::waitKey(KEY_F8); 122 | std::cout << "检测到F8键\n\n"; 123 | 124 | std::cout << "按F9键继续...\n"; 125 | tc::waitKey(KEY_F9); 126 | std::cout << "检测到F9键\n\n"; 127 | 128 | // 可能会触发窗口焦点 129 | /* 130 | std::cout << "按F10键继续...\n"; 131 | tc::waitKey(KEY_F10); 132 | std::cout << "检测到F10键\n\n"; 133 | */ 134 | 135 | // 可能会触发控制台窗口全屏 136 | /* 137 | std::cout << "按F11键继续...\n"; 138 | tc::waitKey(KEY_F11); 139 | std::cout << "检测到F11键\n\n"; 140 | */ 141 | 142 | std::cout << "按F12键继续...\n"; 143 | tc::waitKey(KEY_F12); 144 | std::cout << "检测到F12键\n\n"; 145 | 146 | std::cout << "所有按键测试完成!按任意键退出...\n"; 147 | tc::waitKey(); 148 | 149 | return 0; 150 | } -------------------------------------------------------------------------------- /include/tc_progress.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tc_progress.hpp - TC库进度条模块 3 | * TC Progress Bar Module 4 | * 5 | * 这个文件包含了TC库中的进度条功能,包括: 6 | * - 可自定义的文本进度条 7 | * - 支持自定义宽度、字符和颜色 8 | * - 实时进度显示和百分比 9 | * - 进度完成提示功能 10 | * 11 | * This file contains progress bar functionality in the TC library, including: 12 | * - Customizable text progress bar 13 | * - Support for custom width, characters and colors 14 | * - Real-time progress display and percentage 15 | * - Progress completion notification 16 | * 17 | * 版本 Version: 1.1.1 18 | * 作者 Author: 537 Studio 19 | * 许可 License: MIT 20 | */ 21 | 22 | #ifndef TC_PROGRESS_HPP 23 | #define TC_PROGRESS_HPP 24 | 25 | // 标准库包含 | Standard library includes 26 | #include // 输入输出流 | Input/output streams 27 | #include // 字符串类 | String class 28 | #include "tc_colors.hpp" // TC颜色模块 | TC color module 29 | 30 | namespace tc { 31 | 32 | /** 33 | * 进度条类 34 | * Progress bar class 35 | * 36 | * 这个类提供了一个可自定义的文本进度条,用于显示操作的进度。 37 | * 进度条可以自定义宽度、完成和未完成部分的字符,以及颜色。 38 | * 支持实时更新进度和显示自定义消息。 39 | * 40 | * This class provides a customizable text progress bar for displaying operation progress. 41 | * The progress bar can be customized with width, characters for completed and uncompleted parts, and color. 42 | * Supports real-time progress updates and custom message display. 43 | */ 44 | class ProgressBar { 45 | private: 46 | int width_; // 进度条宽度(字符数) | Progress bar width (in characters) 47 | std::string done_; // 已完成部分的字符 | Character for completed parts 48 | std::string todo_; // 未完成部分的字符 | Character for uncompleted parts 49 | std::string color_; // 进度条颜色(ANSI颜色代码) | Progress bar color (ANSI color code) 50 | 51 | public: 52 | /** 53 | * 构造函数 54 | * Constructor 55 | * 56 | * @param width 进度条宽度 | Progress bar width 57 | * @param done 已完成部分的字符,默认为"#" | Character for completed parts, defaults to "#" 58 | * @param todo 未完成部分的字符,默认为"-" | Character for uncompleted parts, defaults to "-" 59 | * @param color 进度条颜色,默认为绿色 | Progress bar color, defaults to green 60 | */ 61 | ProgressBar(int width, std::string done = "#", std::string todo = "-", std::string color = TCOLOR_GREEN) 62 | : width_(width), done_(std::move(done)), todo_(std::move(todo)), color_(std::move(color)) {} 63 | 64 | /** 65 | * 显示进度条 66 | * Show progress bar 67 | * 68 | * 根据当前进度值显示进度条,包括进度条本体、百分比和自定义消息。 69 | * 使用\r回车符实现在同一行更新进度显示。 70 | * 71 | * Displays the progress bar based on current progress value, including progress bar body, 72 | * percentage and custom message. Uses \r carriage return for same-line progress updates. 73 | * 74 | * @param progress 进度值(0.0-1.0) | Progress value (0.0-1.0) 75 | * @param msg 显示在进度条旁的消息 | Message to display next to the progress bar 76 | */ 77 | void show(double progress, const std::string& msg = "Loading...") { 78 | // 计算已完成部分的位置 | Calculate position of completed part 79 | int pos = static_cast(width_ * progress); 80 | 81 | // 输出进度条 | Output progress bar 82 | std::cout << "\r" << color_ << "["; // 回车并开始进度条 | Carriage return and start progress bar 83 | 84 | // 绘制进度条主体 | Draw progress bar body 85 | for (int i = 0; i < width_; ++i) { 86 | std::cout << (i < pos ? done_ : todo_); // 根据位置输出已完成或未完成字符 | Output completed or uncompleted character based on position 87 | } 88 | 89 | // 输出百分比和消息 | Output percentage and message 90 | std::cout << "] " << int(progress * 100) << "% " << msg << TCOLOR_RESET << std::flush; 91 | } 92 | 93 | /** 94 | * 完成进度条 95 | * Finish progress bar 96 | * 97 | * 显示100%进度并换行,通常在操作完成时调用。 98 | * 这个函数会自动显示100%的进度并添加换行符。 99 | * 100 | * Shows 100% progress and adds a newline, typically called when operation is complete. 101 | * This function automatically displays 100% progress and adds a newline character. 102 | * 103 | * @param content 完成时显示的消息 | Message to display when finished 104 | */ 105 | void finish(std::string content = "Finished") { 106 | show(1.0, content); // 显示100%进度 | Show 100% progress 107 | std::cout << std::endl; // 换行 | Add newline 108 | } 109 | }; 110 | 111 | } // namespace tc 112 | 113 | #endif // TC_PROGRESS_HPP -------------------------------------------------------------------------------- /example/20_terminal_printer_demo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 20_terminal_printer_demo.cpp - 终端控制与Printer链式类示例 3 | * Terminal Control and Printer Chain Class Example 4 | * 5 | * 这个示例展示了如何使用TC库的terminal命名空间和Printer链式类 6 | * 来控制终端,包括清屏、移动光标、获取终端大小等功能。 7 | * 8 | * This example demonstrates how to use the TC library's terminal namespace 9 | * and Printer chain class to control the terminal, including clearing the screen, 10 | * moving the cursor, getting terminal size, etc. 11 | */ 12 | 13 | #include "../include/tc.hpp" 14 | #include 15 | #include 16 | 17 | // 使用terminal命名空间演示 18 | void demoTerminalNamespace() { 19 | std::cout << TCOLOR_CYAN << "=== tc::terminal命名空间演示 ===" << TCOLOR_RESET << std::endl; 20 | tc::wait(1); 21 | 22 | // 清屏 23 | tc::terminal::clear(); 24 | std::cout << "已清屏" << std::endl; 25 | tc::wait(1); 26 | 27 | // 移动光标到指定位置 28 | tc::terminal::moveCursor(20, 10); 29 | std::cout << "移动到位置(20,10)" << std::endl; 30 | tc::wait(1); 31 | 32 | // 获取终端大小 33 | auto [width, height] = tc::terminal::getSize(); 34 | tc::terminal::moveCursor(1, height - 2); 35 | std::cout << "终端大小: " << width << "x" << height << std::endl; 36 | tc::wait(2); 37 | } 38 | 39 | // 使用Printer链式类演示 40 | void demoPrinterClass() { 41 | std::cout << TCOLOR_MAGENTA << "=== tc::Printer链式类演示 ===" << TCOLOR_RESET << std::endl; 42 | tc::wait(1); 43 | 44 | // 创建Printer对象 45 | auto p = tc::printer(); 46 | 47 | // 链式调用多个方法 48 | p.clear() 49 | .hideCursor() 50 | .moveCursor(10, 5) 51 | .print(TCOLOR_GREEN).print("位置(10,5)").print(TCOLOR_RESET) 52 | .println() 53 | .moveCursor(tc::Printer::Direction::Down, 2) 54 | .println("向下移动了2行") 55 | .moveCursor(tc::Printer::Direction::Right, 5) 56 | .println("向右移动了5格") 57 | .moveCursor(1, 10) 58 | .print("在第10行: ") 59 | .print(TCOLOR_YELLOW).print("黄色文本").print(TCOLOR_RESET) 60 | .println() 61 | .showCursor(); 62 | 63 | // 获取终端大小 64 | auto [width, height] = p.getSize(); 65 | p.moveCursor(1, height - 2) 66 | .println("终端大小: ", width, "x", height); 67 | 68 | tc::wait(2); 69 | } 70 | 71 | // 演示相对光标移动 72 | void demoRelativeCursorMovement() { 73 | std::cout << TCOLOR_GREEN << "=== 相对光标移动演示 ===" << TCOLOR_RESET << std::endl; 74 | tc::wait(1); 75 | 76 | auto p = tc::printer(); 77 | p.clear() 78 | .moveCursor(10, 5) 79 | .print("起始位置"); 80 | 81 | // 向各个方向移动 82 | p.moveCursor(tc::Printer::Direction::Down, 2) 83 | .print("↓ 向下2行"); 84 | 85 | p.moveCursor(tc::Printer::Direction::Right, 10) 86 | .print("→ 向右10格"); 87 | 88 | p.moveCursor(tc::Printer::Direction::Up, 1) 89 | .print("↑ 向上1行"); 90 | 91 | p.moveCursor(tc::Printer::Direction::Left, 5) 92 | .print("← 向左5格"); 93 | 94 | // 移动到底部 95 | auto [width, height] = p.getSize(); 96 | p.moveCursor(1, height - 2) 97 | .println("相对光标移动可以更方便地创建复杂的终端界面"); 98 | 99 | tc::wait(2); 100 | } 101 | 102 | // 演示无闪烁更新 103 | void demoFlickerFreeUpdate() { 104 | std::cout << TCOLOR_YELLOW << "=== 无闪烁更新演示 ===" << TCOLOR_RESET << std::endl; 105 | tc::wait(1); 106 | 107 | auto p = tc::printer(); 108 | p.clear() 109 | .hideCursor() 110 | .moveCursor(10, 5) 111 | .println("这是一个无闪烁更新的演示"); 112 | 113 | // 在固定位置更新计数器 114 | p.moveCursor(10, 7) 115 | .print("计数: "); 116 | 117 | // 记住计数器的位置 118 | int counterX = 17; 119 | int counterY = 7; 120 | 121 | // 更新计数器而不清屏 122 | for (int i = 0; i <= 10; i++) { 123 | p.moveCursor(counterX, counterY) 124 | .print(" ") // 清除之前的数字 125 | .moveCursor(counterX, counterY) 126 | .print(i); 127 | 128 | tc::wait(0.5); 129 | } 130 | 131 | p.moveCursor(10, 9) 132 | .println("演示完成,没有屏幕闪烁!") 133 | .showCursor(); 134 | 135 | tc::wait(2); 136 | } 137 | 138 | int main() { 139 | // 演示terminal命名空间 140 | demoTerminalNamespace(); 141 | 142 | // 演示Printer链式类 143 | demoPrinterClass(); 144 | 145 | // 演示相对光标移动 146 | demoRelativeCursorMovement(); 147 | 148 | // 演示无闪烁更新 149 | demoFlickerFreeUpdate(); 150 | 151 | // 清屏并显示结束信息 152 | tc::terminal::clear(); 153 | std::cout << TCOLOR_GREEN << "所有演示完成!" << TCOLOR_RESET << std::endl; 154 | 155 | return 0; 156 | } -------------------------------------------------------------------------------- /doc/ansi_code_reference.md: -------------------------------------------------------------------------------- 1 | # ANSI 转义码完整参考 2 | 3 | 本文档提供了 TC.hpp 库中使用的 ANSI 转义码的详细参考,包括颜色、样式、光标控制等。 4 | 5 | ## 基本格式 6 | 7 | ANSI 转义序列的基本格式为:`\033[<参数>m`,其中 `\033` 是 ASCII 转义字符(ESC),`[` 是控制序列引导符,`<参数>` 是控制参数,`m` 是序列终止符。 8 | 9 | ## 文本样式控制 10 | 11 | | 代码 | 效果 | 兼容性 | 12 | |------|------|--------| 13 | | `\033[0m` | 重置所有样式 | 所有终端 | 14 | | `\033[1m` | 粗体/加粗 | 大多数终端 | 15 | | `\033[2m` | 微弱/淡色 | 部分终端 | 16 | | `\033[3m` | 斜体 | 部分终端 | 17 | | `\033[4m` | 下划线 | 大多数终端 | 18 | | `\033[5m` | 慢速闪烁 | 部分终端 | 19 | | `\033[6m` | 快速闪烁 | 很少终端 | 20 | | `\033[7m` | 反色(前景色与背景色交换) | 大多数终端 | 21 | | `\033[8m` | 隐藏(不可见文本) | 部分终端 | 22 | | `\033[9m` | 删除线 | 部分终端 | 23 | | `\033[21m` | 双下划线/关闭粗体 | 部分终端 | 24 | | `\033[22m` | 关闭粗体和微弱 | 大多数终端 | 25 | | `\033[23m` | 关闭斜体 | 部分终端 | 26 | | `\033[24m` | 关闭下划线 | 大多数终端 | 27 | | `\033[25m` | 关闭闪烁 | 部分终端 | 28 | | `\033[27m` | 关闭反色 | 大多数终端 | 29 | | `\033[28m` | 关闭隐藏 | 部分终端 | 30 | | `\033[29m` | 关闭删除线 | 部分终端 | 31 | 32 | ## 前景色(文字颜色) 33 | 34 | ### 标准颜色 35 | 36 | | 代码 | 颜色 | 37 | |------|------| 38 | | `\033[30m` | 黑色 | 39 | | `\033[31m` | 红色 | 40 | | `\033[32m` | 绿色 | 41 | | `\033[33m` | 黄色 | 42 | | `\033[34m` | 蓝色 | 43 | | `\033[35m` | 洋红/紫色 | 44 | | `\033[36m` | 青色 | 45 | | `\033[37m` | 白色 | 46 | | `\033[39m` | 默认前景色 | 47 | 48 | ### 亮色 49 | 50 | | 代码 | 颜色 | 51 | |------|------| 52 | | `\033[90m` | 亮黑色(灰色) | 53 | | `\033[91m` | 亮红色 | 54 | | `\033[92m` | 亮绿色 | 55 | | `\033[93m` | 亮黄色 | 56 | | `\033[94m` | 亮蓝色 | 57 | | `\033[95m` | 亮洋红/紫色 | 58 | | `\033[96m` | 亮青色 | 59 | | `\033[97m` | 亮白色 | 60 | 61 | ## 背景色 62 | 63 | ### 标准背景色 64 | 65 | | 代码 | 颜色 | 66 | |------|------| 67 | | `\033[40m` | 黑色背景 | 68 | | `\033[41m` | 红色背景 | 69 | | `\033[42m` | 绿色背景 | 70 | | `\033[43m` | 黄色背景 | 71 | | `\033[44m` | 蓝色背景 | 72 | | `\033[45m` | 洋红/紫色背景 | 73 | | `\033[46m` | 青色背景 | 74 | | `\033[47m` | 白色背景 | 75 | | `\033[49m` | 默认背景色 | 76 | 77 | ### 亮色背景 78 | 79 | | 代码 | 颜色 | 80 | |------|------| 81 | | `\033[100m` | 亮黑色(灰色)背景 | 82 | | `\033[101m` | 亮红色背景 | 83 | | `\033[102m` | 亮绿色背景 | 84 | | `\033[103m` | 亮黄色背景 | 85 | | `\033[104m` | 亮蓝色背景 | 86 | | `\033[105m` | 亮洋红/紫色背景 | 87 | | `\033[106m` | 亮青色背景 | 88 | | `\033[107m` | 亮白色背景 | 89 | 90 | ## 256色模式 91 | 92 | ANSI 支持 256 色模式,格式为: 93 | 94 | - 前景色:`\033[38;5;<颜色代码>m` 95 | - 背景色:`\033[48;5;<颜色代码>m` 96 | 97 | 其中 `<颜色代码>` 范围为 0-255: 98 | - 0-7: 标准颜色 99 | - 8-15: 亮色 100 | - 16-231: 6×6×6 RGB 颜色立方体 101 | - 232-255: 灰度色阶 102 | 103 | ## RGB真彩色 104 | 105 | ANSI 支持 24 位真彩色(1670 万色),格式为: 106 | 107 | - 前景色:`\033[38;2;;;m` 108 | - 背景色:`\033[48;2;;;m` 109 | 110 | 其中 ``, ``, `` 分别是 RGB 三个分量的值(0-255)。 111 | 112 | ## 光标控制 113 | 114 | | 代码 | 功能 | 115 | |------|------| 116 | | `\033[H` | 将光标移动到屏幕左上角(1,1) | 117 | | `\033[<行>;<列>H` | 将光标移动到指定位置 | 118 | | `\033[A` | 光标上移 n 行 | 119 | | `\033[B` | 光标下移 n 行 | 120 | | `\033[C` | 光标右移 n 列 | 121 | | `\033[D` | 光标左移 n 列 | 122 | | `\033[E` | 光标下移 n 行,并移到行首 | 123 | | `\033[F` | 光标上移 n 行,并移到行首 | 124 | | `\033[G` | 光标移动到当前行的第 n 列 | 125 | | `\033[s` | 保存光标位置 | 126 | | `\033[u` | 恢复保存的光标位置 | 127 | 128 | ## 清除屏幕 129 | 130 | | 代码 | 功能 | 131 | |------|------| 132 | | `\033[J` | 清除从光标到屏幕末尾的内容 | 133 | | `\033[1J` | 清除从光标到屏幕开头的内容 | 134 | | `\033[2J` | 清除整个屏幕 | 135 | | `\033[3J` | 清除整个屏幕和滚动缓冲区(部分终端支持) | 136 | | `\033[K` | 清除从光标到行末的内容 | 137 | | `\033[1K` | 清除从光标到行首的内容 | 138 | | `\033[2K` | 清除整行 | 139 | 140 | ## 特殊控制 141 | 142 | | 代码 | 功能 | 143 | |------|------| 144 | | `\033[?25l` | 隐藏光标 | 145 | | `\033[?25h` | 显示光标 | 146 | | `\033[?47h` | 切换到备用屏幕缓冲区 | 147 | | `\033[?47l` | 切换回主屏幕缓冲区 | 148 | | `\033[?1049h` | 切换到备用屏幕缓冲区并保存当前屏幕 | 149 | | `\033[?1049l` | 恢复保存的屏幕并切换回主屏幕缓冲区 | 150 | 151 | ## 组合使用 152 | 153 | ANSI 转义码可以组合使用,多个参数用分号分隔: 154 | 155 | ``` 156 | \033[1;31;43m // 粗体、红色文本、黄色背景 157 | ``` 158 | 159 | ## 兼容性注意事项 160 | 161 | 1. **Windows 支持**: 162 | - Windows 10 以前的 CMD 不原生支持 ANSI 转义序列 163 | - Windows 10 及以上版本的控制台支持大部分 ANSI 转义序列 164 | - TC.hpp 在 Windows 平台上**不使用** ANSI 转义序列,而是直接使用 Windows Console API (Win32 API) 实现所有终端控制功能 165 | 166 | 2. **终端类型**: 167 | - 不同的终端模拟器对 ANSI 转义序列的支持程度不同 168 | - 现代终端(如 iTerm2、GNOME Terminal、Windows Terminal)支持大多数功能 169 | - 旧终端或简单终端可能只支持基本功能 170 | 171 | 3. **颜色深度**: 172 | - 并非所有终端都支持 256 色或真彩色 173 | - 不支持的终端会降级到最接近的颜色 174 | 175 | ## 在 TC.hpp 中的使用 176 | 177 | TC.hpp 库封装了这些 ANSI 转义码(在非Windows平台上)和Windows Console API(在Windows平台上),提供了统一的跨平台接口: 178 | 179 | ```cpp 180 | // 使用预定义宏 181 | tc::println(TCOLOR_RED, "红色文本", TCOLOR_RESET); 182 | 183 | // 使用 RGB 颜色 184 | tc::println(TCOLOR_RGB(255, 128, 0), "橙色文本", TCOLOR_RESET); 185 | 186 | // 使用光标控制 187 | tc::printer().moveCursor(10, 5).print("在位置(10,5)打印"); 188 | ``` 189 | 190 | TC.hpp 会自动处理不同平台的兼容性问题,使开发者可以专注于功能实现而不必担心底层细节。在Windows平台上,所有颜色、字体样式和终端控制功能都通过Win32 API直接实现,因此能够完全支持,不受终端对ANSI转义序列支持程度的限制。 191 | -------------------------------------------------------------------------------- /include/tc.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tc.hpp - TC库主头文件 3 | * TC Library Main Header File 4 | * 5 | * 版本 Version: 1.1.1 6 | * 7 | * 这是TC(Terminal Control)库的主头文件,一个现代化的C++17终端控制库。 8 | * TC库提供了跨平台的终端颜色、样式、光标控制、进度条等功能, 9 | * 支持Windows/Linux/macOS,零依赖,纯头文件设计。 10 | * 11 | * This is the main header file for the TC (Terminal Control) library, a modern C++17 terminal control library. 12 | * TC library provides cross-platform terminal colors, styles, cursor control, progress bars and other features, 13 | * supporting Windows/Linux/macOS with zero dependencies and header-only design. 14 | * 15 | * 在线仓库 Online repository: 16 | * - https://github.com/Sean537/TC 17 | * - https://gitee.com/sean537/TC 18 | * 19 | * 版权所有 Copyright (C) 2024-2025 537 Studio. All rights reserved. 20 | * 21 | * 贡献者 Contributors: 22 | * - Sean537 23 | * - RabbitMax 24 | * - L.U. 25 | * 26 | * 功能模块 Feature Modules: 27 | * - 颜色和样式控制 Color and style control (tc_colors.hpp) 28 | * - 打印输出功能 Print output functionality (tc_print.hpp) 29 | * - 等待和按键处理 Wait and key handling (tc_wait.hpp) 30 | * - 终端控制操作 Terminal control operations (tc_terminal.hpp) 31 | * - 流式输出和延时 Stream output and delay (tc_stream.hpp) 32 | * - 进度条显示 Progress bar display (tc_progress.hpp) 33 | * - 系统检测功能 System detection functionality (tc_system.hpp) 34 | * - 系统工具函数 System utility functions (tc_system_utils.hpp) 35 | * 36 | * 许可证 License: MIT 37 | */ 38 | 39 | #ifndef TC_HPP 40 | #define TC_HPP 41 | 42 | /** 43 | * TC库版本号 44 | * TC library version number 45 | */ 46 | #define TC_VERSION "1.1.1" 47 | 48 | /** 49 | * 包含所需的标准库头文件 50 | * Include required standard library headers 51 | * 52 | * 这些标准库头文件提供了TC库运行所需的基础功能,包括: 53 | * - 输入输出流操作 54 | * - 字符串处理 55 | * - 线程和时间操作 56 | * - 智能指针和函数对象 57 | * - 模板元编程支持 58 | * 59 | * These standard library headers provide the basic functionality required for TC library operation, including: 60 | * - Input/output stream operations 61 | * - String processing 62 | * - Thread and time operations 63 | * - Smart pointers and function objects 64 | * - Template metaprogramming support 65 | */ 66 | #include // 标准输入输出流 | Standard input/output streams 67 | #include // 字符串类 | String class 68 | #include // 字符串流 | String streams 69 | #include // 线程库 | Thread library 70 | #include // 时间库 | Time library 71 | #include // 智能指针 | Smart pointers 72 | #include // 函数对象 | Function objects 73 | #include // 类型特性 | Type traits 74 | #include // 栈容器 | Stack container 75 | 76 | /** 77 | * 平台特定头文件包含 78 | * Platform-specific header includes 79 | * 80 | * 根据编译平台包含相应的系统头文件,以支持平台特定的功能: 81 | * - Windows: Windows API、IO操作、文件控制 82 | * - Unix/Linux/macOS: POSIX API、系统IO控制 83 | * 84 | * Include appropriate system headers based on compilation platform to support platform-specific features: 85 | * - Windows: Windows API, IO operations, file control 86 | * - Unix/Linux/macOS: POSIX API, system IO control 87 | */ 88 | #ifdef _WIN32 // Windows平台 | Windows platform 89 | #include // Windows API函数和数据类型 | Windows API functions and data types 90 | #include // Windows IO操作函数 | Windows IO operation functions 91 | #include // 文件控制选项 | File control options 92 | #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING 93 | // 定义ANSI转义序列支持标志(如果未定义) | Define ANSI escape sequence support flag (if not defined) 94 | #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 95 | #endif 96 | #else // 非Windows平台(Unix/Linux/macOS等) | Non-Windows platforms (Unix/Linux/macOS etc.) 97 | #include // POSIX API,提供sleep等函数 | POSIX API providing functions like sleep 98 | #include // 终端IO控制,用于获取终端大小 | Terminal IO control for getting terminal size 99 | #endif 100 | 101 | /** 102 | * 包含各功能模块 103 | * Include functional modules 104 | * 105 | * TC库采用模块化设计,将不同功能分离到独立的头文件中, 106 | * 便于维护和理解。每个模块都有特定的职责和功能。 107 | * 108 | * TC library uses modular design, separating different functions into independent header files 109 | * for easy maintenance and understanding. Each module has specific responsibilities and functions. 110 | */ 111 | #include "tc_colors.hpp" // 颜色和样式相关功能 | Color and style related functionality 112 | #include "tc_print.hpp" // 打印功能 | Print functionality 113 | #include "tc_wait.hpp" // 等待和按键处理 | Wait and key handling 114 | #include "tc_terminal.hpp" // 终端控制 | Terminal control 115 | #include "tc_stream.hpp" // 流式输出和延时 | Stream output and delay 116 | #include "tc_progress.hpp" // 进度条 | Progress bar 117 | #include "tc_system.hpp" // 系统检测 | System detection 118 | #include "tc_system_utils.hpp" // 系统工具 | System utilities 119 | 120 | #endif // TC_HPP -------------------------------------------------------------------------------- /include/tc_print.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tc_print.hpp - TC库打印功能模块 3 | * TC Print Functionality Module 4 | * 5 | * 这个文件包含了TC库中所有与打印输出相关的功能,包括: 6 | * - Python风格的print和println函数 7 | * - 支持可变参数的打印函数 8 | * - 链式调用的PrintProxy类 9 | * - 多参数一次性打印支持 10 | * 11 | * This file contains all print output related functionality in the TC library, including: 12 | * - Python-style print and println functions 13 | * - Variadic parameter print functions 14 | * - Chainable PrintProxy class 15 | * - Multi-parameter one-time print support 16 | * 17 | * 版本 Version: 1.1.1 18 | * 作者 Author: 537 Studio 19 | * 许可 License: MIT 20 | */ 21 | 22 | #ifndef TC_PRINT_HPP 23 | #define TC_PRINT_HPP 24 | 25 | // 标准库包含 | Standard library includes 26 | #include // 输入输出流 | Input/output streams 27 | #include // 初始化列表 | Initializer list 28 | 29 | namespace tc { 30 | 31 | /** 32 | * PrintProxy类 - 提供链式调用风格的打印功能 33 | * PrintProxy class - Provides chainable printing functionality 34 | * 35 | * 这个类允许类似Python的链式打印操作,如:print("Hello").print(" ").println("World") 36 | * 支持任意数量和类型的参数,使用完美转发来保持参数的值类别。 37 | * 38 | * This class allows Python-like chaining of print operations, e.g.: print("Hello").print(" ").println("World") 39 | * Supports any number and type of arguments, using perfect forwarding to preserve argument value categories. 40 | */ 41 | class PrintProxy { 42 | public: 43 | /** 44 | * 无参数打印,返回自身引用以支持链式调用 45 | * No-argument print, returns self-reference for chaining 46 | * 47 | * @return 对象自身引用 | Self reference 48 | */ 49 | const PrintProxy& print() const { return *this; } 50 | 51 | /** 52 | * 可变参数模板打印,支持任意数量和类型的参数 53 | * Variadic template print, supports any number and type of arguments 54 | * 55 | * 使用初始化列表技巧展开参数包,通过完美转发保持参数的原始类型。 56 | * Uses initializer list trick to expand parameter pack, preserving original types through perfect forwarding. 57 | * 58 | * @param args 要打印的参数 | Arguments to print 59 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 60 | */ 61 | template 62 | const PrintProxy& print(Args&&... args) const { 63 | (void)std::initializer_list{(std::cout << std::forward(args), 0)...}; 64 | return *this; 65 | } 66 | 67 | /** 68 | * 可变参数模板行打印,带换行符 69 | * Variadic template line print with newline 70 | * 71 | * 打印所有参数后自动添加换行符。 72 | * Automatically adds newline after printing all arguments. 73 | * 74 | * @param args 要打印的参数 | Arguments to print 75 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 76 | */ 77 | template 78 | const PrintProxy& println(Args&&... args) const { 79 | (void)std::initializer_list{(std::cout << std::forward(args), 0)...}; 80 | std::cout << std::endl; 81 | return *this; 82 | } 83 | }; 84 | 85 | /** 86 | * 全局print函数,返回PrintProxy实例以支持链式调用 87 | * Global print function, returns PrintProxy instance for chaining 88 | * 89 | * 使用静态局部变量确保只有一个PrintProxy实例。 90 | * Uses static local variable to ensure only one PrintProxy instance. 91 | * 92 | * @return PrintProxy实例引用 | PrintProxy instance reference 93 | */ 94 | inline const PrintProxy& print() { 95 | static PrintProxy p; 96 | return p; 97 | } 98 | 99 | /** 100 | * 全局println函数,输出换行符并返回PrintProxy实例 101 | * Global println function, outputs newline and returns PrintProxy instance 102 | * 103 | * @return PrintProxy实例引用 | PrintProxy instance reference 104 | */ 105 | inline const PrintProxy& println() { 106 | static PrintProxy p; 107 | std::cout << std::endl; 108 | return p; 109 | } 110 | 111 | /** 112 | * 全局print/println函数 - 支持一次性多参数打印 113 | * Global print/println functions - Support one-time multi-parameter printing 114 | * 115 | * 这些函数提供了简单的接口来打印多个参数,类似于Python的print函数。 116 | * 使用可变参数模板和完美转发来支持任意类型和数量的参数。 117 | * 118 | * These functions provide a simple interface to print multiple arguments, similar to Python's print function. 119 | * Uses variadic templates and perfect forwarding to support any type and number of arguments. 120 | */ 121 | 122 | /** 123 | * 全局print函数,一次性打印多个参数 124 | * Global print function, prints multiple arguments at once 125 | * 126 | * @param args 要打印的参数 | Arguments to print 127 | */ 128 | template 129 | inline void print(Args&&... args) { 130 | (void)std::initializer_list{(std::cout << std::forward(args), 0)...}; 131 | } 132 | 133 | /** 134 | * 全局println函数,一次性打印多个参数并换行 135 | * Global println function, prints multiple arguments and adds newline 136 | * 137 | * @param args 要打印的参数 | Arguments to print 138 | */ 139 | template 140 | inline void println(Args&&... args) { 141 | (void)std::initializer_list{(std::cout << std::forward(args), 0)...}; 142 | std::cout << std::endl; 143 | } 144 | 145 | } // namespace tc 146 | 147 | #endif // TC_PRINT_HPP -------------------------------------------------------------------------------- /example/15_interactive_cli.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class CLI { 8 | private: 9 | std::string prompt_; 10 | std::map&)>, std::string>> commands_; 11 | bool running_ = true; 12 | 13 | std::vector splitCommand(const std::string& input) { 14 | std::vector parts; 15 | std::string part; 16 | bool inQuotes = false; 17 | 18 | for (char c : input) { 19 | if (c == '"') { 20 | inQuotes = !inQuotes; 21 | } else if (c == ' ' && !inQuotes) { 22 | if (!part.empty()) { 23 | parts.push_back(part); 24 | part.clear(); 25 | } 26 | } else { 27 | part += c; 28 | } 29 | } 30 | 31 | if (!part.empty()) { 32 | parts.push_back(part); 33 | } 34 | 35 | return parts; 36 | } 37 | 38 | public: 39 | CLI(const std::string& prompt = "> ") : prompt_(prompt) { 40 | // 添加内置命令 41 | addCommand("help", [this](const std::vector& args) { 42 | tc::println(TCOLOR_CYAN, TFONT_BOLD, "可用命令:", TCOLOR_RESET); 43 | for (const auto& cmd : commands_) { 44 | tc::println(TCOLOR_YELLOW, cmd.first, TCOLOR_RESET, " - ", cmd.second.second); 45 | } 46 | }, "显示帮助信息"); 47 | 48 | addCommand("exit", [this](const std::vector& args) { 49 | tc::println(TCOLOR_GREEN, "再见!", TCOLOR_RESET); 50 | running_ = false; 51 | }, "退出程序"); 52 | 53 | addCommand("clear", [](const std::vector& args) { 54 | tc::printer().clear(); 55 | }, "清屏"); 56 | } 57 | 58 | void addCommand(const std::string& name, 59 | std::function&)> handler, 60 | const std::string& description) { 61 | commands_[name] = {handler, description}; 62 | } 63 | 64 | void run() { 65 | tc::println(TCOLOR_GREEN, TFONT_BOLD, "交互式命令行界面", TCOLOR_RESET); 66 | tc::println("输入 'help' 获取帮助,输入 'exit' 退出"); 67 | 68 | while (running_) { 69 | tc::print(TCOLOR_CYAN, prompt_, TCOLOR_RESET); 70 | 71 | std::string input; 72 | std::getline(std::cin, input); 73 | 74 | if (input.empty()) continue; 75 | 76 | std::vector parts = splitCommand(input); 77 | std::string cmd = parts[0]; 78 | 79 | if (commands_.find(cmd) != commands_.end()) { 80 | // 提取参数 81 | std::vector args(parts.begin() + 1, parts.end()); 82 | 83 | try { 84 | commands_[cmd].first(args); 85 | } catch (const std::exception& e) { 86 | tc::println(TCOLOR_RED, "错误: ", e.what(), TCOLOR_RESET); 87 | } 88 | } else { 89 | tc::println(TCOLOR_RED, "未知命令: ", cmd, TCOLOR_RESET); 90 | tc::println("输入 'help' 获取可用命令列表"); 91 | } 92 | } 93 | } 94 | }; 95 | 96 | int main() { 97 | CLI cli("TC> "); 98 | 99 | // 添加自定义命令 100 | cli.addCommand("echo", [](const std::vector& args) { 101 | for (const auto& arg : args) { 102 | tc::print(arg, " "); 103 | } 104 | tc::println(); 105 | }, "回显参数"); 106 | 107 | cli.addCommand("color", [](const std::vector& args) { 108 | if (args.empty()) { 109 | tc::println(TCOLOR_RED, "用法: color <颜色名> <文本>", TCOLOR_RESET); 110 | return; 111 | } 112 | 113 | std::string color = args[0]; 114 | std::string text = args.size() > 1 ? args[1] : "彩色文本测试"; 115 | 116 | if (color == "red") { 117 | tc::println(TCOLOR_RED, text, TCOLOR_RESET); 118 | } else if (color == "green") { 119 | tc::println(TCOLOR_GREEN, text, TCOLOR_RESET); 120 | } else if (color == "blue") { 121 | tc::println(TCOLOR_BLUE, text, TCOLOR_RESET); 122 | } else if (color == "yellow") { 123 | tc::println(TCOLOR_YELLOW, text, TCOLOR_RESET); 124 | } else if (color == "cyan") { 125 | tc::println(TCOLOR_CYAN, text, TCOLOR_RESET); 126 | } else if (color == "magenta") { 127 | tc::println(TCOLOR_MAGENTA, text, TCOLOR_RESET); 128 | } else { 129 | tc::println(TCOLOR_RED, "未知颜色: ", color, TCOLOR_RESET); 130 | } 131 | }, "使用指定颜色显示文本"); 132 | 133 | cli.addCommand("time", [](const std::vector& args) { 134 | tc::println("当前时间: ", 135 | tc::getSystemTime(SYS_YEAR), "-", 136 | tc::getSystemTime(SYS_MONTH), "-", 137 | tc::getSystemTime(SYS_DAY), " ", 138 | tc::getSystemTime(SYS_HOUR), ":", 139 | tc::getSystemTime(SYS_MINUTE), ":", 140 | tc::getSystemTime(SYS_SECOND)); 141 | }, "显示当前时间"); 142 | 143 | cli.run(); 144 | 145 | return 0; 146 | } -------------------------------------------------------------------------------- /doc/os_support.md: -------------------------------------------------------------------------------- 1 | # 操作系统支持与系统检测 2 | 3 | 本文档描述了 tc_system.hpp 中的操作系统支持和系统检测功能。 4 | 5 | ## 操作系统宏定义 6 | 7 | 以下是 tc_system.hpp 中定义的操作系统宏,按类型分类: 8 | 9 | ### 未知操作系统 10 | 11 | | 宏定义 | 数值 | 描述 | 12 | |-------|------|------| 13 | | OS_UNKNOWN | 0 | 无法识别的操作系统 | 14 | 15 | ### Windows 系列 16 | 17 | | 宏定义 | 数值 | 描述 | 18 | |-------|------|------| 19 | | OS_WINDOWS | 100 | 通用Windows标识 | 20 | | OS_WINDOWSNT6 | 108 | Windows 7/8/8.1 (NT 6.x) | 21 | | OS_WINDOWSNT10 | 109 | Windows 10 (NT 10.0) | 22 | | OS_WINDOWSNT11 | 110 | Windows 11 (NT 10.0 build 22000+) | 23 | 24 | ### Linux 发行版 25 | 26 | | 宏定义 | 数值 | 描述 | 27 | |-------|------|------| 28 | | OS_LINUX | 200 | 通用Linux标识 | 29 | | OS_UBUNTU | 201 | Ubuntu Linux | 30 | | OS_DEBIAN | 202 | Debian Linux | 31 | | OS_FEDORA | 203 | Fedora Linux | 32 | | OS_CENTOS | 204 | CentOS Linux | 33 | | OS_REDHAT | 205 | Red Hat Enterprise Linux | 34 | | OS_SUSE | 206 | SUSE/openSUSE Linux | 35 | | OS_ARCH | 207 | Arch Linux | 36 | | OS_GENTOO | 208 | Gentoo Linux | 37 | | OS_SLACKWARE | 209 | Slackware Linux | 38 | | OS_ANDROID | 210 | Android (基于Linux) | 39 | | OS_KALI | 211 | Kali Linux | 40 | | OS_MINT | 212 | Linux Mint | 41 | | OS_MANJARO | 213 | Manjaro Linux | 42 | | OS_ALPINE | 214 | Alpine Linux | 43 | | OS_RASPBIAN | 215 | Raspbian | 44 | | OS_DEEPIN | 216 | Deepin Linux | 45 | | OS_ELEMENTARY | 217 | Elementary OS | 46 | | OS_ZORIN | 218 | Zorin OS | 47 | | OS_POPOS | 219 | Pop!_OS | 48 | | OS_CHROMEOS | 220 | Chrome OS/Chromium OS | 49 | 50 | ### Apple 操作系统 51 | 52 | | 宏定义 | 数值 | 描述 | 53 | |-------|------|------| 54 | | OS_MACOS | 300 | 通用macOS标识 | 55 | | OS_MACOS_HIGHSIERRA | 324 | macOS 10.13 High Sierra (2017) | 56 | | OS_MACOS_MOJAVE | 325 | macOS 10.14 Mojave (2018) | 57 | | OS_MACOS_CATALINA | 326 | macOS 10.15 Catalina (2019) | 58 | | OS_MACOS_BIGSUR | 327 | macOS 11 Big Sur (2020) | 59 | | OS_MACOS_MONTEREY | 328 | macOS 12 Monterey (2021) | 60 | | OS_MACOS_VENTURA | 329 | macOS 13 Ventura (2022) | 61 | | OS_MACOS_SONOMA | 330 | macOS 14 Sonoma (2023) | 62 | | OS_MACOS_SEQUOIA | 331 | macOS 15 Sequoia (2024) | 63 | | OS_MACOS_TAHOE | 332 | macOS 26 Tahoe (2025) | 64 | 65 | ### 其他 Apple 操作系统 66 | 67 | | 宏定义 | 数值 | 描述 | 68 | |-------|------|------| 69 | | OS_IOS | 350 | iOS (iPhone/iPod touch) | 70 | | OS_IPADOS | 351 | iPadOS (iPad) | 71 | | OS_WATCHOS | 352 | watchOS (Apple Watch) | 72 | | OS_TVOS | 353 | tvOS (Apple TV) | 73 | | OS_VISIONOS | 354 | visionOS (Apple Vision Pro) | 74 | | OS_BRIDGEOS | 355 | bridgeOS (Apple T2芯片) | 75 | | OS_AUDIOOS | 356 | audioOS (HomePod) | 76 | 77 | ### BSD 系列 78 | 79 | | 宏定义 | 数值 | 描述 | 80 | |-------|------|------| 81 | | OS_BSD | 400 | 通用BSD标识 | 82 | | OS_FREEBSD | 404 | FreeBSD | 83 | 84 | ### Unix 系列 85 | 86 | | 宏定义 | 数值 | 描述 | 87 | |-------|------|------| 88 | | OS_UNIX | 500 | 通用Unix标识 | 89 | 90 | ### 新兴操作系统 91 | 92 | | 宏定义 | 数值 | 描述 | 93 | |-------|------|------| 94 | | OS_FUCHSIA | 950 | Google Fuchsia | 95 | | OS_HARMONYOS | 952 | Harmony OS | 96 | 97 | ### 其它操作系统 98 | 99 | | 宏定义 | 数值 | 描述 | 100 | |-------|------|------| 101 | | OS_REACTOS | 1000 | ReactOS (基于Windows NT的开源操作系统)| 102 | 103 | ## 已删除的操作系统 104 | 105 | 以下是已从 tc_system.hpp 中删除的操作系统宏,因为它们不支持本库需要的 C++17: 106 | 107 | 1. Windows 旧版本: 108 | - Windows 95 (OS_WIN95) 109 | - Windows 98 (OS_WIN98) 110 | - Windows ME (OS_WINME) 111 | - Windows CE (OS_WINCE) 112 | - Windows NT 3.x (OS_WINDOWSNT3) 113 | - Windows NT 4.0 (OS_WINDOWSNT4) 114 | - Windows 2000/XP/2003 (OS_WINDOWSNT5) 115 | - Windows Vista (包含在 OS_WINDOWSNT6 中,但已从检测代码中移除) 116 | 117 | 2. macOS 旧版本: 118 | - 经典 Mac OS 系统 (OS_MACOS1 到 OS_MACOS9) 119 | - Mac OS X 10.0 Cheetah 到 10.12 Sierra (OS_MACOSX_CHEETAH 到 OS_MACOS_SIERRA) 120 | - Mac OS X Server 系列 121 | 122 | 3. 其他已删除的操作系统: 123 | - DOS 系列 (OS_DOS) 124 | - BeOS 系列 (OS_BEOS, OS_HAIKU 等) 125 | - 旧 Unix 系统 (OS_HURD, OS_XENIX) 126 | - 商业 Unix 系统 (OS_AIX, OS_SOLARIS 等) 127 | - 嵌入式操作系统 (OS_NUTTX, OS_ZEPHYR 等) 128 | - 其他不支持 C++17 的操作系统 129 | 130 | ## 系统检测功能 131 | 132 | tc_system.hpp 提供了以下系统检测相关的函数: 133 | 134 | ### systemCheck() 135 | 136 | ```cpp 137 | inline int systemCheck(); 138 | ``` 139 | 140 | 此函数通过各种平台特定的API和检测方法,识别当前运行的操作系统类型和版本。它返回一个整数代码,对应于上述宏定义中的一个。 141 | 142 | 特点: 143 | - 使用运行时检测而非仅依赖编译时宏 144 | - 对于Windows系统,使用RtlGetVersion、GetVersionEx和PowerShell命令获取真实版本号 145 | - 对于macOS系统,使用sw_vers命令和sysctlbyname获取版本信息 146 | - 对于iOS/iPadOS/watchOS等系统,通过硬件型号(hw.machine)识别设备类型 147 | - 对于Linux系统,使用lsb_release命令、/etc/os-release文件和uname命令识别发行版 148 | 149 | ### getOSName(int osCode) 150 | 151 | ```cpp 152 | inline const char* getOSName(int osCode); 153 | ``` 154 | 155 | 此函数根据systemCheck()返回的操作系统代码,返回对应的操作系统名称字符串。 156 | 157 | ### getOSVersionInfo() 158 | 159 | ```cpp 160 | inline std::string getOSVersionInfo(); 161 | ``` 162 | 163 | 此函数获取当前操作系统的详细版本信息,包括版本号、构建号等。 164 | 165 | ## 使用示例 166 | 167 | ```cpp 168 | #include "tc.hpp" 169 | #include 170 | 171 | int main() { 172 | // 获取系统信息 173 | int osCode = tc::systemCheck(); 174 | const char* osName = tc::getOSName(osCode); 175 | std::string osVersionInfo = tc::getOSVersionInfo(); 176 | 177 | // 显示系统信息 178 | std::cout << "操作系统代码: " << osCode << std::endl; 179 | std::cout << "操作系统名称: " << osName << std::endl; 180 | std::cout << "操作系统版本: " << osVersionInfo << std::endl; 181 | 182 | return 0; 183 | } 184 | ``` 185 | 186 | ## 注意事项 187 | 188 | 1. 系统检测功能在运行时执行,因此能够准确识别当前运行的操作系统,而不仅仅依赖于编译时的宏定义。 189 | 190 | 2. 对于苹果设备,特别是在macOS上交叉编译的iOS/iPadOS应用,系统检测会通过硬件型号和系统特性进行识别,而不仅仅依赖于编译时的TARGET_OS_*宏。 191 | 192 | 3. 对于Linux系统,会尝试多种方法识别具体的发行版,包括lsb_release命令、/etc/os-release文件和特定发行版的标识文件。 -------------------------------------------------------------------------------- /doc/tc_quick_start.md: -------------------------------------------------------------------------------- 1 | # TC.hpp 快速入门指南 2 | 3 | > TC.hpp 是一个现代化的 C++17 终端控制库,支持彩色输出、字体样式、延时、进度条、终端控制等,跨平台、零依赖、纯头文件。 4 | 5 | ## 目录 6 | 7 | - [安装](#安装) 8 | - [基本用法](#基本用法) 9 | - [颜色输出](#颜色输出) 10 | - [字体样式](#字体样式) 11 | - [延时与等待](#延时与等待) 12 | - [进度条](#进度条) 13 | - [终端控制](#终端控制) 14 | - [系统相关功能](#系统相关功能) 15 | - [编译说明](#编译说明) 16 | - [常见问题](#常见问题) 17 | 18 | ## 安装 19 | 20 | TC.hpp 是一个纯头文件库,无需安装,只需将 `tc.hpp` 文件复制到您的项目中,然后包含它即可: 21 | 22 | ```cpp 23 | #include "tc.hpp" 24 | ``` 25 | 26 | ## 基本用法 27 | 28 | ### 标准输出 29 | 30 | TC.hpp 提供了类似 Python 的 print/println 函数: 31 | 32 | ```cpp 33 | // 多参数打印 34 | tc::print("Hello", " ", "World"); // 输出: Hello World 35 | tc::println("Hello", " ", "World"); // 输出: Hello World 并换行 36 | 37 | // 打印不同类型的值 38 | tc::println("年龄: ", 25, ", 分数: ", 95.5); 39 | ``` 40 | 41 | ### 流式输出 42 | 43 | TC.hpp 还提供了流式输出接口: 44 | 45 | ```cpp 46 | // 流式输出 47 | tc::tout << "Hello World" << std::endl; 48 | ``` 49 | 50 | ## 颜色输出 51 | 52 | ### 使用颜色宏 53 | 54 | ```cpp 55 | // 红色文本 56 | tc::println(TCOLOR_RED, "红色文本", TCOLOR_RESET); 57 | 58 | // 绿色文本,黄色背景 59 | tc::println(TCOLOR_GREEN, BCOLOR_YELLOW, "绿色文字,黄色背景", TCOLOR_RESET); 60 | 61 | // 蓝色粗体,白色背景 62 | tc::println(TCOLOR_BLUE, BCOLOR_WHITE, TFONT_BOLD, "蓝色粗体,白色背景", TCOLOR_RESET); 63 | ``` 64 | 65 | ### 流式颜色输出 66 | 67 | ```cpp 68 | tc::tout << TCOLOR_RED << "红色文本" << TCOLOR_RESET << std::endl; 69 | ``` 70 | 71 | ### RGB 颜色 72 | 73 | ```cpp 74 | tc::println(TCOLOR_RGB(255, 0, 0), "自定义红色", TCOLOR_RESET); 75 | tc::tout << TCOLOR_RGB(0, 255, 0) << "自定义绿色" << TCOLOR_RESET << std::endl; 76 | ``` 77 | 78 | ## 字体样式 79 | 80 | ```cpp 81 | // 粗体 82 | tc::println(TFONT_BOLD, "粗体文本", TFONT_RESET); 83 | 84 | // 下划线 85 | tc::println(TFONT_UNDERLINE, "下划线文本", TFONT_RESET); 86 | 87 | // 斜体 88 | tc::println(TFONT_ITALIC, "斜体文本", TFONT_RESET); 89 | 90 | // 删除线 91 | tc::println(TFONT_CROSSED, "删除线文本", TFONT_RESET); 92 | 93 | // 组合样式 94 | tc::println(TFONT_BOLD, TFONT_UNDERLINE, "粗体下划线文本", TFONT_RESET); 95 | ``` 96 | 97 | ## 延时与等待 98 | 99 | ### 延时函数 100 | 101 | ```cpp 102 | // 等待指定秒数(支持小数) 103 | tc::wait(1.5); // 等待1.5秒 104 | 105 | // 等待指定毫秒 106 | tc::tsleep(1000).execute(); // 等待1000毫秒 107 | 108 | // 流式延时 109 | tc::tout << "等待前" << tc::tsleep(500) << "等待后" << std::endl; 110 | 111 | // 延时流 112 | tc::tsleep_stream << 1000; // 等待1000毫秒 113 | ``` 114 | 115 | ### 按键等待 116 | 117 | ```cpp 118 | // 等待任意按键 119 | tc::println("按任意键继续..."); 120 | tc::waitKey(); 121 | 122 | // 等待特定按键 123 | tc::println("按 A 键继续..."); 124 | tc::waitKey('A'); 125 | 126 | // 等待ESC键 127 | tc::println("按 ESC 键退出..."); 128 | tc::waitKey(KEY_ESC); 129 | ``` 130 | 131 | ## 进度条 132 | 133 | ```cpp 134 | // 创建进度条(宽度30,填充字符"█",未填充字符"░",绿色) 135 | tc::ProgressBar bar(30, "█", "░", TCOLOR_GREEN); 136 | 137 | // 显示进度(0.0-1.0之间) 138 | for (int i = 0; i <= 100; ++i) { 139 | bar.show(i / 100.0, "处理中..."); 140 | tc::wait(0.02); // 模拟处理时间 141 | } 142 | 143 | // 完成进度条 144 | bar.finish("完成!"); 145 | ``` 146 | 147 | ## 终端控制 148 | 149 | ### 光标控制 150 | 151 | ```cpp 152 | // 清屏 153 | tc::printer().clear(); 154 | 155 | // 移动光标到指定位置 156 | tc::printer().moveCursor(10, 5); // 移动到第5行,第10列 157 | tc::println("在位置(10,5)打印"); 158 | 159 | // 隐藏/显示光标 160 | tc::printer().hideCursor(); 161 | tc::wait(1.0); // 光标隐藏1秒 162 | tc::printer().showCursor(); 163 | 164 | // 相对移动光标 165 | tc::printer().moveCursor(tc::Printer::Direction::Up, 2); // 上移2行 166 | tc::printer().moveCursor(tc::Printer::Direction::Right, 5); // 右移5列 167 | ``` 168 | 169 | ### 终端尺寸 170 | 171 | ```cpp 172 | // 获取终端窗口大小 173 | auto size = tc::printer().getSize(); 174 | tc::println("终端大小: ", size.first, "x", size.second); // 宽x高 175 | ``` 176 | 177 | ## 系统相关功能 178 | 179 | ### 系统时间 180 | 181 | ```cpp 182 | // 获取当前年份 183 | int year = tc::getSystemTime(SYS_YEAR); 184 | 185 | // 获取当前月份 186 | int month = tc::getSystemTime(SYS_MONTH); 187 | 188 | // 获取当前日期 189 | int day = tc::getSystemTime(SYS_DAY); 190 | 191 | // 获取当前时间 192 | tc::println("当前日期: ", 193 | tc::getSystemTime(SYS_YEAR), "-", 194 | tc::getSystemTime(SYS_MONTH), "-", 195 | tc::getSystemTime(SYS_DAY), " ", 196 | tc::getSystemTime(SYS_HOUR), ":", 197 | tc::getSystemTime(SYS_MINUTE), ":", 198 | tc::getSystemTime(SYS_SECOND)); 199 | 200 | // 获取Unix时间戳 201 | int timestamp = tc::getSystemTime(); // 默认返回时间戳 202 | tc::println("Unix时间戳: ", timestamp); 203 | ``` 204 | 205 | ### 系统命令 206 | 207 | ```cpp 208 | // 执行系统命令 209 | tc::systemConsole("echo Hello World"); 210 | ``` 211 | 212 | ### 系统检测 213 | 214 | ```cpp 215 | // 获取当前操作系统类型 216 | int os = tc::systemCheck(); 217 | 218 | // 根据返回值判断系统类型 219 | switch (os) { 220 | case OS_WINDOWSNT11: 221 | tc::println("Windows 11"); 222 | break; 223 | case OS_WINDOWSNT10: 224 | tc::println("Windows 10"); 225 | break; 226 | case OS_LINUX: 227 | tc::println("Linux"); 228 | break; 229 | case OS_MACOS: 230 | tc::println("macOS"); 231 | break; 232 | default: 233 | tc::println("其他系统, code=", os); 234 | } 235 | ``` 236 | 237 | ## 编译说明 238 | 239 | TC.hpp 需要 C++17 或更高版本的编译器支持。 240 | 241 | ### Windows 242 | 243 | ```bash 244 | g++ -std=c++17 your_program.cpp -o your_program.exe 245 | ``` 246 | 247 | ### Linux/macOS 248 | 249 | ```bash 250 | g++ -std=c++17 -pthread your_program.cpp -o your_program 251 | ``` 252 | 253 | ## 常见问题 254 | 255 | ### 1. Windows 下颜色显示问题 256 | 257 | TC.hpp 在 Windows 平台上使用 Windows Console API(Win32 API)实现终端控制功能,而不使用 ANSI 转义序列,因此能够在所有 Windows 版本上正常工作,包括旧版 CMD。如果您遇到颜色显示问题,请确保您的终端支持彩色输出。 258 | 259 | ### 2. 某些字体样式不生效 260 | 261 | 不同终端对 ANSI 转义序列的支持程度不同。例如,斜体、删除线等在某些终端可能不受支持。请参考 [ANSI 转义码参考](ansi_code_reference.md) 了解兼容性详情。 262 | 263 | ### 3. 编译错误 264 | 265 | 确保您的编译器支持 C++17 标准,并且正确包含了 tc.hpp 文件。 266 | 267 | ### 4. 在 Linux/macOS 下编译时出现线程相关错误 268 | 269 | 在 Linux/macOS 下编译时,需要添加 `-pthread` 选项以支持线程功能: 270 | 271 | ```bash 272 | g++ -std=c++17 -pthread your_program.cpp -o your_program 273 | ``` 274 | 275 | --- 276 | 277 | 更多详细信息,请参考: 278 | - [TC.hpp 功能文档](tc_functionality.md) 279 | - [TC.hpp API 参考手册](tc_api_reference.md) 280 | - [ANSI 转义码参考](ansi_code_reference.md) -------------------------------------------------------------------------------- /example/02_color_output.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 02_color_output.cpp - 颜色功能示例 3 | * Color Functions Example 4 | * 5 | * 这个示例展示了TC库中所有颜色控制功能的用法, 6 | * 包括全局颜色宏、ColorController类、颜色包装器类和便捷颜色函数。 7 | * 8 | * This example demonstrates the usage of all color control features in the TC library, 9 | * including global color macros, ColorController class, color wrapper classes, 10 | * and convenient color functions. 11 | */ 12 | 13 | #include "../include/tc.hpp" 14 | #include 15 | #include 16 | 17 | // 演示全局颜色宏 18 | void demoGlobalMacros() { 19 | std::cout << TCOLOR_CYAN << "=== 全局颜色宏演示 ===" << TCOLOR_RESET << std::endl; 20 | 21 | // 前景色 22 | tc::println(TCOLOR_RED, "红色文本", TCOLOR_RESET); 23 | tc::println(TCOLOR_GREEN, "绿色文本", TCOLOR_RESET); 24 | tc::println(TCOLOR_BLUE, "蓝色文本", TCOLOR_RESET); 25 | tc::println(TCOLOR_YELLOW, "黄色文本", TCOLOR_RESET); 26 | tc::println(TCOLOR_MAGENTA, "洋红文本", TCOLOR_RESET); 27 | tc::println(TCOLOR_CYAN, "青色文本", TCOLOR_RESET); 28 | tc::println(TCOLOR_WHITE, "白色文本", TCOLOR_RESET); 29 | 30 | // 背景色 31 | tc::println(TCOLOR_BLACK, BCOLOR_RED, "黑字红底", TCOLOR_RESET); 32 | tc::println(TCOLOR_WHITE, BCOLOR_BLUE, "白字蓝底", TCOLOR_RESET); 33 | tc::println(TCOLOR_BLACK, BCOLOR_GREEN, "黑字绿底", TCOLOR_RESET); 34 | tc::println(TCOLOR_BLACK, BCOLOR_YELLOW, "黑字黄底", TCOLOR_RESET); 35 | 36 | // 组合使用 37 | std::cout << TCOLOR_RED << BCOLOR_YELLOW << "红字黄底" << TCOLOR_RESET << std::endl; 38 | std::cout << TCOLOR_BLUE << BCOLOR_WHITE << "蓝字白底" << TCOLOR_RESET << std::endl; 39 | 40 | // 字体样式 41 | std::cout << TFONT_BOLD << "粗体文本" << TFONT_RESET << std::endl; 42 | std::cout << TFONT_UNDERLINE << "下划线文本" << TFONT_RESET << std::endl; 43 | std::cout << TFONT_ITALIC << "斜体文本" << TFONT_RESET << std::endl; 44 | std::cout << TFONT_BLINK_SLOW << "闪烁文本" << TFONT_RESET << std::endl; 45 | std::cout << TFONT_REVERSE << "反色文本" << TFONT_RESET << std::endl; 46 | 47 | // RGB颜色 48 | tc::println(TCOLOR_RGB(255, 128, 0), "橙色文本 (RGB: 255,128,0)", TCOLOR_RESET); 49 | tc::println(TCOLOR_RGB(128, 0, 255), "紫色文本 (RGB: 128,0,255)", TCOLOR_RESET); 50 | tc::println(TCOLOR_RGB(0, 255, 128), "薄荷绿文本 (RGB: 0,255,128)", TCOLOR_RESET); 51 | 52 | // 流式颜色输出 53 | tc::tout << TCOLOR_RED << "红色" << TCOLOR_GREEN << "绿色" 54 | << TCOLOR_BLUE << "蓝色" << TCOLOR_RESET << std::endl; 55 | 56 | tc::wait(1); 57 | } 58 | 59 | // 演示ColorController类 60 | void demoColorController() { 61 | std::cout << TCOLOR_CYAN << "=== ColorController类演示 ===" << TCOLOR_RESET << std::endl; 62 | 63 | // 设置颜色 64 | tc::ColorController::setColor(tc::ColorController::Color::RED); 65 | std::cout << "红色文本" << std::endl; 66 | 67 | tc::ColorController::setColor(tc::ColorController::Color::BRIGHT_GREEN); 68 | std::cout << "亮绿色文本" << std::endl; 69 | 70 | tc::ColorController::setColor(tc::ColorController::Color::BLUE); 71 | std::cout << "蓝色文本" << std::endl; 72 | 73 | // 设置RGB颜色 74 | tc::ColorController::setRGBColor(255, 128, 0); 75 | std::cout << "橙色文本 (RGB: 255,128,0)" << std::endl; 76 | 77 | // 设置粗体 78 | tc::ColorController::setBold(true); 79 | std::cout << "粗体文本" << std::endl; 80 | 81 | // 重置所有属性 82 | tc::ColorController::setColor(tc::ColorController::Color::RESET); 83 | std::cout << "正常文本" << std::endl; 84 | 85 | tc::wait(1); 86 | } 87 | 88 | // 演示颜色包装器类 89 | void demoColorWrappers() { 90 | std::cout << TCOLOR_CYAN << "=== 颜色包装器类演示 ===" << TCOLOR_RESET << std::endl; 91 | 92 | // 使用ColorWrapper 93 | std::cout << tc::ColorWrapper(tc::ColorController::Color::RED) << "红色文本" 94 | << tc::ColorWrapper(tc::ColorController::Color::RESET) << std::endl; 95 | 96 | // 使用RGBColorWrapper 97 | std::cout << tc::RGBColorWrapper(255, 128, 0) << "橙色文本" 98 | << tc::ColorWrapper(tc::ColorController::Color::RESET) << std::endl; 99 | 100 | // 使用FontStyleWrapper 101 | std::cout << tc::FontStyleWrapper(true) << "粗体文本" 102 | << tc::FontStyleWrapper(false) << std::endl; 103 | 104 | tc::wait(1); 105 | } 106 | 107 | // 演示便捷颜色函数 108 | void demoColorFunctions() { 109 | std::cout << TCOLOR_CYAN << "=== 便捷颜色函数演示 ===" << TCOLOR_RESET << std::endl; 110 | 111 | // 使用colorize函数 112 | std::string coloredText = tc::colorize("青色文本", tc::ColorController::Color::CYAN); 113 | std::cout << coloredText << std::endl; 114 | 115 | // 使用便捷颜色函数 116 | std::cout << tc::red("红色文本") << std::endl; 117 | std::cout << tc::green("绿色文本") << std::endl; 118 | std::cout << tc::blue("蓝色文本") << std::endl; 119 | std::cout << tc::yellow("黄色文本") << std::endl; 120 | 121 | // 组合使用 122 | std::string message = "重要提示"; 123 | std::cout << tc::colorize(message, tc::ColorController::Color::BRIGHT_RED) << std::endl; 124 | 125 | tc::wait(1); 126 | } 127 | 128 | // 演示实际应用场景 129 | void demoRealWorldUsage() { 130 | std::cout << TCOLOR_CYAN << "=== 实际应用场景演示 ===" << TCOLOR_RESET << std::endl; 131 | 132 | // 模拟日志输出 133 | std::cout << TCOLOR_GREEN << "[INFO] " << TCOLOR_RESET << "系统启动成功" << std::endl; 134 | std::cout << TCOLOR_YELLOW << "[WARN] " << TCOLOR_RESET << "磁盘空间不足" << std::endl; 135 | std::cout << TCOLOR_RED << "[ERROR] " << TCOLOR_RESET << "无法连接到服务器" << std::endl; 136 | 137 | // 模拟命令行界面 138 | std::cout << std::endl << TFONT_BOLD << "命令行菜单:" << TFONT_RESET << std::endl; 139 | std::cout << TCOLOR_CYAN << "1. " << TCOLOR_RESET << "查看文件" << std::endl; 140 | std::cout << TCOLOR_CYAN << "2. " << TCOLOR_RESET << "编辑文件" << std::endl; 141 | std::cout << TCOLOR_CYAN << "3. " << TCOLOR_RESET << "删除文件" << std::endl; 142 | std::cout << TCOLOR_CYAN << "0. " << TCOLOR_RESET << "退出" << std::endl; 143 | 144 | // 模拟代码高亮 145 | std::cout << std::endl << TFONT_BOLD << "代码高亮示例:" << TFONT_RESET << std::endl; 146 | std::cout << TCOLOR_BLUE << "int" << TCOLOR_RESET << " main() {" << std::endl; 147 | std::cout << " " << TCOLOR_GREEN << "std::cout" << TCOLOR_RESET << " << " 148 | << TCOLOR_YELLOW << "\"Hello, World!\"" << TCOLOR_RESET << " << " 149 | << TCOLOR_GREEN << "std::endl" << TCOLOR_RESET << ";" << std::endl; 150 | std::cout << " " << TCOLOR_BLUE << "return" << TCOLOR_RESET << " 0;" << std::endl; 151 | std::cout << "}" << std::endl; 152 | 153 | tc::wait(1); 154 | } 155 | 156 | int main() { 157 | // 清屏 158 | tc::terminal::clear(); 159 | 160 | std::cout << TFONT_BOLD << "TC库颜色功能演示" << TFONT_RESET << std::endl; 161 | std::cout << "======================" << std::endl << std::endl; 162 | 163 | // 演示全局颜色宏 164 | demoGlobalMacros(); 165 | std::cout << std::endl; 166 | 167 | // 演示ColorController类 168 | demoColorController(); 169 | std::cout << std::endl; 170 | 171 | // 演示颜色包装器类 172 | demoColorWrappers(); 173 | std::cout << std::endl; 174 | 175 | // 演示便捷颜色函数 176 | demoColorFunctions(); 177 | std::cout << std::endl; 178 | 179 | // 演示实际应用场景 180 | demoRealWorldUsage(); 181 | std::cout << std::endl; 182 | 183 | // 结束信息 184 | std::cout << TCOLOR_GREEN << "所有颜色功能演示完成!" << TCOLOR_RESET << std::endl; 185 | 186 | return 0; 187 | } 188 | -------------------------------------------------------------------------------- /include/tc_stream.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tc_stream.hpp - TC库流式输出和延时模块 3 | * TC Stream Output and Delay Module 4 | * 5 | * 这个文件包含了TC库中的流式输出和延时功能,包括: 6 | * - 增强的输出流类(TOut) 7 | * - 延时操作类(TSleep) 8 | * - 流式延时操作类(TSleepStream) 9 | * - 支持颜色和样式的流式输出 10 | * 11 | * This file contains stream output and delay functionality in the TC library, including: 12 | * - Enhanced output stream class (TOut) 13 | * - Delay operation class (TSleep) 14 | * - Stream-style delay operation class (TSleepStream) 15 | * - Stream output with color and style support 16 | * 17 | * 版本 Version: 1.1.1 18 | * 作者 Author: 537 Studio 19 | * 许可 License: MIT 20 | */ 21 | 22 | #ifndef TC_STREAM_HPP 23 | #define TC_STREAM_HPP 24 | 25 | // 标准库包含 | Standard library includes 26 | #include // 输入输出流 | Input/output streams 27 | #include // 线程库 | Thread library 28 | #include // 时间库 | Time library 29 | #include "tc_colors.hpp" // TC颜色模块 | TC color module 30 | 31 | namespace tc { 32 | 33 | /** 34 | * 延时操作类 35 | * Sleep operation class 36 | * 37 | * 这个类封装了延时操作,便于在流式输出中使用。 38 | * 可以直接用于流式输出,如:std::cout << "等待开始" << TSleep(1000) << "等待结束"; 39 | * 40 | * This class encapsulates sleep operations for easy use in stream output. 41 | * Can be used directly in stream output, e.g.: std::cout << "Wait starts" << TSleep(1000) << "Wait ends"; 42 | */ 43 | class TSleep { 44 | private: 45 | int milliseconds_; // 延时的毫秒数 | Milliseconds to sleep 46 | 47 | public: 48 | /** 49 | * 构造函数 50 | * Constructor 51 | * 52 | * @param ms 延时的毫秒数 | Milliseconds to sleep 53 | */ 54 | explicit TSleep(int ms) : milliseconds_(ms) {} 55 | 56 | /** 57 | * 执行延时操作 58 | * Execute sleep operation 59 | */ 60 | void execute() const { 61 | // 使用标准库的线程休眠功能 | Use standard library thread sleep functionality 62 | std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds_)); 63 | } 64 | 65 | /** 66 | * 输出流操作符重载,使对象可以直接用于流式输出 67 | * Output stream operator overload, allowing the object to be used directly in stream output 68 | * 69 | * @param os 输出流 | Output stream 70 | * @param sleep 延时操作对象 | Sleep operation object 71 | * @return 输出流引用,用于链式调用 | Output stream reference for chaining 72 | */ 73 | friend std::ostream& operator<<(std::ostream& os, const TSleep& sleep) { 74 | sleep.execute(); // 执行延时 | Execute sleep 75 | return os; 76 | } 77 | }; 78 | 79 | /** 80 | * 自定义输出流类 81 | * Custom output stream class 82 | * 83 | * 这个类提供了增强的输出流功能,支持链式输出和自定义类型。 84 | * 它可以处理颜色、RGB颜色、字体样式和延时操作等特殊类型。 85 | * 86 | * This class provides enhanced output stream functionality, supporting chain output and custom types. 87 | * It can handle special types like colors, RGB colors, font styles, and sleep operations. 88 | */ 89 | class TOut { 90 | private: 91 | std::ostream& os_; // 底层输出流引用 | Reference to underlying output stream 92 | 93 | public: 94 | /** 95 | * 构造函数 96 | * Constructor 97 | * 98 | * @param os 底层输出流,默认为标准输出 | Underlying output stream, defaults to standard output 99 | */ 100 | explicit TOut(std::ostream& os = std::cout) : os_(os) { 101 | #ifdef _WIN32 102 | // 确保Windows控制台已初始化 | Ensure Windows console is initialized 103 | Win32Console::getInstance(); 104 | #endif 105 | } 106 | 107 | /** 108 | * 通用输出操作符,处理任意类型的值 109 | * Generic output operator, handles values of any type 110 | * 111 | * 使用完美转发来保持参数的原始类型和值类别。 112 | * Uses perfect forwarding to preserve original type and value category of arguments. 113 | * 114 | * @param value 要输出的值 | Value to output 115 | * @return 自身引用,用于链式调用 | Self reference for chaining 116 | */ 117 | template 118 | TOut& operator<<(T&& value) { 119 | os_ << std::forward(value); // 转发值到底层流 | Forward value to underlying stream 120 | return *this; 121 | } 122 | 123 | /** 124 | * 特化的输出操作符,处理延时操作 125 | * Specialized output operator for sleep operations 126 | * 127 | * @param sleep 延时操作对象 | Sleep operation object 128 | * @return 自身引用,用于链式调用 | Self reference for chaining 129 | */ 130 | TOut& operator<<(const TSleep& sleep) { 131 | sleep.execute(); // 执行延时 | Execute sleep 132 | return *this; 133 | } 134 | 135 | /** 136 | * 特化的输出操作符,处理颜色包装器 137 | * Specialized output operator for color wrappers 138 | * 139 | * @param color 颜色包装器对象 | Color wrapper object 140 | * @return 自身引用,用于链式调用 | Self reference for chaining 141 | */ 142 | TOut& operator<<(const ColorWrapper& color) { 143 | os_ << color; // 应用颜色设置 | Apply color setting 144 | return *this; 145 | } 146 | 147 | /** 148 | * 特化的输出操作符,处理RGB颜色包装器 149 | * Specialized output operator for RGB color wrappers 150 | * 151 | * @param color RGB颜色包装器对象 | RGB color wrapper object 152 | * @return 自身引用,用于链式调用 | Self reference for chaining 153 | */ 154 | TOut& operator<<(const RGBColorWrapper& color) { 155 | os_ << color; // 应用RGB颜色设置 | Apply RGB color setting 156 | return *this; 157 | } 158 | 159 | /** 160 | * 特化的输出操作符,处理字体样式包装器 161 | * Specialized output operator for font style wrappers 162 | * 163 | * @param style 字体样式包装器对象 | Font style wrapper object 164 | * @return 自身引用,用于链式调用 | Self reference for chaining 165 | */ 166 | TOut& operator<<(const FontStyleWrapper& style) { 167 | os_ << style; // 应用字体样式设置 | Apply font style setting 168 | return *this; 169 | } 170 | 171 | /** 172 | * 支持标准流操作符,如std::endl 173 | * Support for standard stream manipulators like std::endl 174 | * 175 | * @param manip 流操作符函数 | Stream manipulator function 176 | * @return 自身引用,用于链式调用 | Self reference for chaining 177 | */ 178 | TOut& operator<<(std::ostream& (*manip)(std::ostream&)) { 179 | os_ << manip; // 应用流操作符 | Apply stream manipulator 180 | return *this; 181 | } 182 | 183 | /** 184 | * 获取底层输出流 185 | * Get underlying output stream 186 | * 187 | * @return 底层输出流引用 | Reference to underlying output stream 188 | */ 189 | std::ostream& stream() { return os_; } 190 | }; 191 | 192 | /** 193 | * 全局输出流对象,类似std::cout但具有增强功能 194 | * Global output stream object, similar to std::cout but with enhanced features 195 | * 196 | * 这个对象可以用于所有标准输出操作,并支持颜色、样式和延时等特殊功能。 197 | * 例如:tc::tout << TCOLOR_RED << "红色文本" << TCOLOR_RESET << std::endl; 198 | * 199 | * This object can be used for all standard output operations and supports special features 200 | * like colors, styles, and sleep operations. 201 | * Example: tc::tout << TCOLOR_RED << "Red text" << TCOLOR_RESET << std::endl; 202 | */ 203 | static TOut tout(std::cout); 204 | 205 | /** 206 | * 创建延时操作对象 207 | * Create sleep operation object 208 | * 209 | * @param milliseconds 延时的毫秒数 | Milliseconds to sleep 210 | * @return TSleep对象,可用于流式输出 | TSleep object that can be used in stream output 211 | */ 212 | inline TSleep tsleep(int milliseconds) { 213 | return TSleep(milliseconds); 214 | } 215 | 216 | /** 217 | * 延时流操作符类 218 | * Sleep stream operator class 219 | * 220 | * 这个类提供了另一种延时语法,使用左移操作符。 221 | * 例如:tc::tsleep_stream << 1000; // 延时1秒 222 | * 223 | * This class provides an alternative sleep syntax using the left shift operator. 224 | * Example: tc::tsleep_stream << 1000; // Sleep for 1 second 225 | */ 226 | class TSleepStream { 227 | public: 228 | /** 229 | * 左移操作符重载,执行延时操作 230 | * Left shift operator overload, executes sleep operation 231 | * 232 | * @param milliseconds 延时的毫秒数 | Milliseconds to sleep 233 | */ 234 | void operator<<(int milliseconds) const { 235 | std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); 236 | } 237 | }; 238 | 239 | /** 240 | * 全局延时流对象 241 | * Global sleep stream object 242 | * 243 | * 用于执行流式延旲操作。 244 | * 例如:tc::tsleep_stream << 1000; // 延时1秒 245 | * 246 | * Used for stream-style sleep operations. 247 | * Example: tc::tsleep_stream << 1000; // Sleep for 1 second 248 | */ 249 | static TSleepStream tsleep_stream; 250 | 251 | } // namespace tc 252 | 253 | #endif // TC_STREAM_HPP -------------------------------------------------------------------------------- /doc/tc_terminal_functions.md: -------------------------------------------------------------------------------- 1 | # TC库终端控制功能详解 2 | 3 | 本文档详细说明了TC库中与终端控制相关的功能,包括基本终端控制、缓冲区管理和链式操作接口。TC库提供了多种方式来控制终端输出和显示,使开发者能够创建更加丰富和响应迅速的终端应用程序。 4 | 5 | ## 目录 6 | 7 | 1. [概述](#概述) 8 | 2. [tc::terminal命名空间](#tcterminal命名空间) 9 | 3. [tc::Printer链式函数类](#tcprinter链式函数类) 10 | 4. [缓冲区控制](#缓冲区控制) 11 | 5. [功能对比](#功能对比) 12 | 6. [使用建议](#使用建议) 13 | 7. [示例代码](#示例代码) 14 | 15 | ## 概述 16 | 17 | TC库提供了两种不同风格的终端控制接口: 18 | 19 | 1. **tc::terminal命名空间**:提供了一系列独立的函数,每个函数执行特定的终端操作。这种风格适合简单、直接的终端控制需求。 20 | 21 | 2. **tc::Printer链式函数类**:提供了一个对象式的接口,支持链式调用,可以将多个终端操作连接在一起。这种风格适合复杂的、多步骤的终端控制序列。 22 | 23 | ## tc::terminal命名空间 24 | 25 | `tc::terminal`命名空间包含了一系列用于基本终端控制的函数。这些函数设计简单直接,每次调用执行一个特定的终端操作。 26 | 27 | ### 可用函数 28 | 29 | | 函数名 | 描述 | 参数 | 返回值 | 30 | |--------|------|------|--------| 31 | | `clear()` | 清空终端屏幕并将光标移动到左上角 | 无 | 无 | 32 | | `moveCursor(int x, int y)` | 将光标移动到指定坐标 | `x`: 列坐标(从1开始)
`y`: 行坐标(从1开始) | 无 | 33 | | `getSize()` | 获取终端窗口大小 | 无 | `std::pair`: 包含宽度和高度的对组 | 34 | | `flush()` | 刷新终端输出缓冲区 | 无 | 无 | 35 | 36 | ### 使用示例 37 | 38 | ```cpp 39 | // 基本终端控制 40 | tc::terminal::clear(); 41 | tc::terminal::moveCursor(5, 3); 42 | 43 | // 获取终端大小 44 | auto [width, height] = tc::terminal::getSize(); 45 | tc::println("终端宽度: ", width, ", 高度: ", height); 46 | 47 | // 使用刷新功能 48 | tc::print("\r加载中..."); 49 | tc::terminal::flush(); // 确保立即显示 50 | ``` 51 | 52 | ## 缓冲区控制 53 | 54 | TC库提供了两种方式来控制终端输出的缓冲,使开发者能够精确控制内容何时显示在屏幕上。这在创建动画效果、实时更新界面或需要即时反馈的交互式应用程序中特别有用。 55 | 56 | ### 全局刷新函数 57 | 58 | `tc::terminal::flush()` 函数会立即刷新终端的输出缓冲区,确保所有待显示的内容立即出现在屏幕上。 59 | 60 | ```cpp 61 | // 使用全局刷新函数 62 | tc::print("\r处理中..."); 63 | tc::terminal::flush(); // 立即显示 64 | tc::wait(1.0); 65 | ``` 66 | 67 | ### Printer类的刷新方法 68 | 69 | `tc::Printer` 类提供了 `flush()` 方法,支持链式调用: 70 | 71 | ```cpp 72 | // 使用Printer的刷新方法 73 | tc::printer() 74 | .print("\r第一步...") 75 | .flush() 76 | .print("\r第二步...") 77 | .flush(); 78 | ``` 79 | 80 | ### 自动刷新场景 81 | 82 | 某些操作会自动触发刷新: 83 | 84 | 1. 使用 `\r` 进行回车时 85 | 2. 使用 `println` 函数时 86 | 3. 某些终端控制操作(如移动光标)后 87 | 88 | ```cpp 89 | // 自动刷新示例 90 | tc::print("\r自动刷新"); // 含\r会自动刷新 91 | tc::println("自动刷新"); // println自动刷新 92 | tc::printer().moveCursor(0, 0).print("位置更新"); // 移动光标后自动刷新 93 | ``` 94 | 95 | ### 应用场景 96 | 97 | 缓冲区控制在以下场景特别有用: 98 | 99 | 1. **动画效果** 100 | ```cpp 101 | tc::printer().hideCursor().flush(); 102 | for (int i = 0; i < 100; i++) { 103 | tc::print("\r进度: ", i, "%"); 104 | tc::terminal::flush(); 105 | tc::wait(0.05); 106 | } 107 | tc::printer().showCursor().flush(); 108 | ``` 109 | 110 | 2. **实时更新界面** 111 | ```cpp 112 | // 更新状态显示 113 | void updateStatus(const std::string& status) { 114 | tc::print("\r当前状态: ", status); 115 | tc::terminal::flush(); 116 | } 117 | ``` 118 | 119 | 3. **交互式应用** 120 | ```cpp 121 | // 即时响应的命令提示符 122 | tc::printer() 123 | .print("> ") 124 | .flush(); // 确保提示符立即显示 125 | std::string command; 126 | std::getline(std::cin, command); 127 | ``` 128 | 129 | ## tc::Printer链式函数类 130 | 131 | `tc::Printer`类提供了一个链式调用接口,允许将多个终端操作连接在一起执行。这种风格特别适合需要执行一系列连续操作的场景。 132 | 133 | ### 创建Printer对象 134 | 135 | 使用`tc::printer()`函数可以创建一个新的`Printer`对象: 136 | 137 | ```cpp 138 | auto p = tc::printer(); 139 | ``` 140 | 141 | ### 可用方法 142 | 143 | | 方法名 | 描述 | 参数 | 返回值 | 144 | |--------|------|------|--------| 145 | | `clear()` | 清空终端屏幕并将光标移动到左上角 | 无 | `Printer&`: 对象自身引用 | 146 | | `moveCursor(int x, int y)` | 将光标移动到指定坐标 | `x`: 列坐标(从1开始)
`y`: 行坐标(从1开始) | `Printer&`: 对象自身引用 | 147 | | `moveCursor(Direction dir, int n)` | 按指定方向移动光标 | `dir`: 移动方向
`n`: 移动步数 | `Printer&`: 对象自身引用 | 148 | | `print()` | 无参数打印函数 | 无 | `Printer&`: 对象自身引用 | 149 | | `print(Args&&... args)` | 可变参数打印函数 | `args`: 要打印的参数 | `Printer&`: 对象自身引用 | 150 | | `println(Args&&... args)` | 可变参数打印函数,带换行 | `args`: 要打印的参数 | `Printer&`: 对象自身引用 | 151 | | `hideCursor()` | 隐藏光标 | 无 | `Printer&`: 对象自身引用 | 152 | | `showCursor()` | 显示光标 | 无 | `Printer&`: 对象自身引用 | 153 | | `getSize()` | 获取终端窗口大小 | 无 | `std::pair`: 包含宽度和高度的对组 | 154 | 155 | ### 方向枚举 156 | 157 | `tc::Printer::Direction`枚举定义了光标移动的方向: 158 | 159 | | 枚举值 | 描述 | 160 | |--------|------| 161 | | `Direction::Up` | 向上移动 | 162 | | `Direction::Down` | 向下移动 | 163 | | `Direction::Left` | 向左移动 | 164 | | `Direction::Right` | 向右移动 | 165 | 166 | ### 使用示例 167 | 168 | ```cpp 169 | // 创建Printer对象 170 | auto p = tc::printer(); 171 | 172 | // 链式调用多个方法 173 | p.clear() 174 | .hideCursor() 175 | .moveCursor(5, 3) 176 | .print("位置(5,3)") 177 | .moveCursor(tc::Printer::Direction::Down, 2) 178 | .println("向下移动了2行") 179 | .showCursor(); 180 | 181 | // 获取终端大小 182 | auto [width, height] = p.getSize(); 183 | p.moveCursor(1, height - 1) 184 | .println("终端宽度: ", width, ", 高度: ", height); 185 | ``` 186 | 187 | ## 功能对比 188 | 189 | 下表比较了`tc::terminal`命名空间和`tc::Printer`类的功能: 190 | 191 | | 功能 | tc::terminal | tc::Printer | 192 | |------|--------------|-------------| 193 | | 清屏 | ✓ | ✓ | 194 | | 移动光标到绝对位置 | ✓ | ✓ | 195 | | 移动光标到相对位置 | ✗ | ✓ | 196 | | 获取终端大小 | ✓ | ✓ | 197 | | 隐藏/显示光标 | ✗ | ✓ | 198 | | 打印文本 | ✗ | ✓ | 199 | | 链式调用 | ✗ | ✓ | 200 | 201 | ## 使用建议 202 | 203 | 1. **简单操作**:对于简单的、独立的终端控制操作,使用`tc::terminal`命名空间中的函数。例如,只需清屏或移动光标一次。 204 | 205 | 2. **复杂序列**:对于需要执行多个连续操作的场景,使用`tc::Printer`类的链式调用接口。例如,需要清屏、移动光标、打印文本、再移动光标等一系列操作。 206 | 207 | 3. **打印功能**:如果需要在终端控制操作中包含打印功能,使用`tc::Printer`类,它提供了`print`和`println`方法。 208 | 209 | 4. **相对移动**:如果需要相对于当前位置移动光标,使用`tc::Printer`类的`moveCursor(Direction, int)`方法。 210 | 211 | ## 示例代码 212 | 213 | ### 使用tc::terminal命名空间 214 | 215 | ```cpp 216 | #include "../include/tc.hpp" 217 | #include 218 | 219 | int main() { 220 | // 清屏 221 | tc::terminal::clear(); 222 | 223 | // 移动光标并打印 224 | tc::terminal::moveCursor(10, 5); 225 | std::cout << "这是位置(10,5)" << std::endl; 226 | 227 | // 获取终端大小 228 | auto [width, height] = tc::terminal::getSize(); 229 | tc::terminal::moveCursor(1, height - 1); 230 | std::cout << "终端大小: " << width << "x" << height << std::endl; 231 | 232 | return 0; 233 | } 234 | ``` 235 | 236 | ### 使用tc::Printer链式函数 237 | 238 | ```cpp 239 | #include "../include/tc.hpp" 240 | #include 241 | 242 | int main() { 243 | // 创建Printer对象并执行一系列操作 244 | tc::printer() 245 | .clear() 246 | .hideCursor() 247 | .moveCursor(10, 5) 248 | .println("这是位置(10,5)") 249 | .moveCursor(tc::Printer::Direction::Down, 2) 250 | .println("向下移动了2行") 251 | .moveCursor(1, 10) 252 | .print("在第10行: ") 253 | .print("继续在同一行打印") 254 | .println() 255 | .showCursor(); 256 | 257 | return 0; 258 | } 259 | ``` 260 | 261 | ### 综合示例 262 | 263 | ```cpp 264 | #include "../include/tc.hpp" 265 | #include 266 | #include 267 | 268 | void demoTerminal() { 269 | std::cout << "=== tc::terminal命名空间演示 ===" << std::endl; 270 | tc::wait(1); 271 | 272 | tc::terminal::clear(); 273 | std::cout << "已清屏" << std::endl; 274 | tc::wait(1); 275 | 276 | tc::terminal::moveCursor(20, 10); 277 | std::cout << "移动到位置(20,10)" << std::endl; 278 | tc::wait(1); 279 | 280 | auto [width, height] = tc::terminal::getSize(); 281 | tc::terminal::moveCursor(1, height - 2); 282 | std::cout << "终端大小: " << width << "x" << height << std::endl; 283 | tc::wait(2); 284 | } 285 | 286 | void demoPrinter() { 287 | std::cout << "=== tc::Printer链式函数演示 ===" << std::endl; 288 | tc::wait(1); 289 | 290 | auto p = tc::printer(); 291 | 292 | p.clear() 293 | .println("已清屏") 294 | .wait(1) 295 | 296 | .moveCursor(20, 10) 297 | .println("移动到位置(20,10)") 298 | .wait(1) 299 | 300 | .moveCursor(tc::Printer::Direction::Left, 5) 301 | .println("向左移动5格") 302 | .wait(1) 303 | 304 | .hideCursor() 305 | .println("光标已隐藏") 306 | .wait(1) 307 | 308 | .showCursor() 309 | .println("光标已显示") 310 | .wait(1); 311 | 312 | auto [width, height] = p.getSize(); 313 | p.moveCursor(1, height - 2) 314 | .println("终端大小: ", width, "x", height); 315 | 316 | tc::wait(2); 317 | } 318 | 319 | int main() { 320 | demoTerminal(); 321 | tc::terminal::clear(); 322 | tc::wait(1); 323 | demoPrinter(); 324 | 325 | return 0; 326 | } 327 | ``` 328 | 329 | 通过以上示例,您可以清楚地了解`tc::terminal`命名空间和`tc::Printer`类的使用方法和区别,从而根据具体需求选择合适的接口。 -------------------------------------------------------------------------------- /include/tc_wait.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tc_wait.hpp - TC库等待和按键处理模块 3 | * TC Wait and Key Handling Module 4 | * 5 | * 这个文件包含了TC库中所有与等待和按键处理相关的功能,包括: 6 | * - 时间延迟函数 7 | * - 跨平台按键等待功能 8 | * - 特定按键等待支持 9 | * 10 | * This file contains all wait and key handling related functionality in the TC library, including: 11 | * - Time delay functions 12 | * - Cross-platform key waiting functionality 13 | * - Specific key waiting support 14 | * 15 | * 版本 Version: 1.1.1 16 | * 作者 Author: 537 Studio 17 | * 许可 License: MIT 18 | */ 19 | 20 | #ifndef TC_WAIT_HPP 21 | #define TC_WAIT_HPP 22 | 23 | // 标准库包含 | Standard library includes 24 | #include // 线程库,用于延时操作 | Thread library for delay operations 25 | #include // 时间相关功能 | Time-related functionality 26 | 27 | // 引入系统工具模块,获取按键码定义 | Include system utils module for key code definitions 28 | #include "tc_system_utils.hpp" 29 | #include 30 | #include 31 | 32 | // 平台特定包含 | Platform-specific includes 33 | #ifdef _WIN32 34 | #include // Windows控制台输入输出函数 | Windows console I/O functions 35 | #else 36 | #include // 终端IO设置 | Terminal I/O settings 37 | #include // POSIX API | POSIX API 38 | #endif 39 | 40 | namespace tc { 41 | 42 | /** 43 | * 等待函数 - 暂停程序执行指定的秒数 44 | * Wait function - Pauses program execution for specified seconds 45 | * 46 | * 这个函数使用C++11的线程库来实现跨平台的精确延时。 47 | * 支持小数秒数,内部转换为毫秒进行延时。 48 | * 49 | * This function uses C++11 thread library to implement cross-platform precise delay. 50 | * Supports decimal seconds, internally converted to milliseconds for delay. 51 | * 52 | * @param seconds 等待的秒数,支持小数 | Number of seconds to wait, supports decimals 53 | */ 54 | inline void wait(double seconds) { 55 | // 将秒转换为毫秒并暂停线程 | Convert seconds to milliseconds and pause thread 56 | std::this_thread::sleep_for(std::chrono::milliseconds((int)(seconds*1000))); 57 | } 58 | 59 | #ifdef _WIN32 // Windows平台实现 | Windows platform implementation 60 | 61 | /** 62 | * waitKey函数 - 等待任意按键按下(Windows版本) 63 | * waitKey function - Waits for any key press (Windows version) 64 | * 65 | * 使用Windows特有的_getch()函数,不需要按回车键即可获取按键输入。 66 | * Uses Windows-specific _getch() function, no need to press Enter to get key input. 67 | */ 68 | inline void waitKey() { 69 | _getch(); // 使用_getch()获取按键,不回显 | Use _getch() to get key without echo 70 | } 71 | 72 | /** 73 | * waitKey函数 - 等待指定字符按键按下(Windows版本) 74 | * waitKey function - Waits for specific character key press (Windows version) 75 | * 76 | * @param key 等待的字符按键 | Character key to wait for 77 | */ 78 | inline void waitKey(char key) { 79 | while (_getch() != key) {} // 循环直到按下指定键 | Loop until specified key is pressed 80 | } 81 | 82 | /** 83 | * waitKey函数 - 等待指定键码按键按下(Windows版本) 84 | * waitKey function - Waits for specific key code press (Windows version) 85 | * 86 | * @param key 等待的键码 | Key code to wait for 87 | */ 88 | inline void waitKey(int key) { 89 | while (_getch() != key) {} // 循环直到按下指定键码 | Loop until specified key code is pressed 90 | } 91 | 92 | #else // 非Windows平台实现 | Non-Windows platform implementation 93 | 94 | /** 95 | * waitKey函数 - 等待任意按键按下(Unix/Linux/macOS版本) 96 | * waitKey function - Waits for any key press (Unix/Linux/macOS version) 97 | * 98 | * 使用termios来设置终端为非规范模式,允许立即读取按键输入。 99 | * Uses termios to set terminal to non-canonical mode for immediate key reading. 100 | */ 101 | inline void waitKey() { 102 | termios oldt, newt; // 终端设置结构体 | Terminal settings structures 103 | tcgetattr(0, &oldt); // 获取当前终端设置 | Get current terminal settings 104 | newt = oldt; 105 | newt.c_lflag &= ~(ICANON | ECHO); // 禁用规范模式和回显,允许立即读取按键且不回显 | Disable canonical mode and echo 106 | tcsetattr(0, TCSANOW, &newt); // 应用新设置 | Apply new settings 107 | getchar(); // 读取一个字符 | Read one character 108 | tcsetattr(0, TCSANOW, &oldt); // 恢复原始设置 | Restore original settings 109 | } 110 | 111 | /** 112 | * waitKey函数 - 等待指定字符按键按下(Unix/Linux/macOS版本) 113 | * waitKey function - Waits for specific character key press (Unix/Linux/macOS version) 114 | * 115 | * @param key 等待的字符按键 | Character key to wait for 116 | */ 117 | inline void waitKey(char key) { 118 | termios oldt, newt; // 终端设置结构体 | Terminal settings structures 119 | tcgetattr(0, &oldt); // 获取当前终端设置 | Get current terminal settings 120 | newt = oldt; 121 | newt.c_lflag &= ~(ICANON | ECHO); // 禁用规范模式和回显,允许立即读取按键且不回显 | Disable canonical mode and echo 122 | tcsetattr(0, TCSANOW, &newt); // 应用新设置 | Apply new settings 123 | int ch; 124 | do { ch = getchar(); } while (ch != key); // 循环直到按下指定键 | Loop until specified key is pressed 125 | tcsetattr(0, TCSANOW, &oldt); // 恢复原始设置 | Restore original settings 126 | } 127 | 128 | /** 129 | * waitKey函数 - 等待指定键码按键按下(Unix/Linux/macOS版本) 130 | * waitKey function - Waits for specific key code press (Unix/Linux/macOS version) 131 | * 132 | * @param key 等待的键码 | Key code to wait for 133 | */ 134 | inline void waitKey(int key) { 135 | termios oldt, newt; 136 | tcgetattr(0, &oldt); 137 | newt = oldt; 138 | newt.c_lflag &= ~(ICANON | ECHO); 139 | tcsetattr(0, TCSANOW, &newt); 140 | std::vector seq; 141 | while (true) { 142 | int ch = getchar(); 143 | if (ch == 27) { 144 | if (key == 27) break; // 直接检测 ESC 键 145 | // ESC 序列 146 | seq.clear(); 147 | seq.push_back(ch); 148 | ch = getchar(); 149 | if (ch == '[') { 150 | seq.push_back(ch); 151 | ch = getchar(); 152 | seq.push_back(ch); 153 | // 收集完整的ESC序列 154 | std::string fullSeq; 155 | fullSeq = "\x1b["; // ESC [ 156 | fullSeq += (char)seq[2]; // 第三个字符 157 | 158 | // 继续读取直到遇到结束符号(如 '~')或字母 159 | while (true) { 160 | ch = getchar(); 161 | fullSeq += (char)ch; 162 | if (ch == '~' || (ch >= 'A' && ch <= 'Z')) { 163 | break; 164 | } 165 | } 166 | 167 | // 方向键 (ESC [ A/B/C/D) 168 | if (fullSeq == "\x1b[A" && key == 'A') break; // 上 169 | if (fullSeq == "\x1b[B" && key == 'B') break; // 下 170 | if (fullSeq == "\x1b[C" && key == 'C') break; // 右 171 | if (fullSeq == "\x1b[D" && key == 'D') break; // 左 172 | 173 | // Home/End (ESC [ H/F) 174 | if (fullSeq == "\x1b[H" && key == KEY_HOME) break; 175 | if (fullSeq == "\x1b[F" && key == KEY_END) break; 176 | 177 | // 功能键 F5-F8 (ESC [ 1 5/6/7/8 ~) 178 | if (fullSeq == "\x1b[15~" && key == 15) break; // F5 179 | if (fullSeq == "\x1b[17~" && key == 17) break; // F6 180 | if (fullSeq == "\x1b[18~" && key == 18) break; // F7 181 | if (fullSeq == "\x1b[19~" && key == 19) break; // F8 182 | 183 | // 功能键 F9-F12 (ESC [ 2 0/1/3/4 ~) 184 | if (fullSeq == "\x1b[20~" && key == 20) break; // F9 185 | if (fullSeq == "\x1b[21~" && key == 21) break; // F10 186 | if (fullSeq == "\x1b[23~" && key == 23) break; // F11 187 | if (fullSeq == "\x1b[24~" && key == 24) break; // F12 188 | 189 | // Insert/Delete/PageUp/PageDown 190 | if (fullSeq == "\x1b[2~" && key == KEY_INSERT) break; 191 | if (fullSeq == "\x1b[3~" && key == KEY_DELETE) break; 192 | if (fullSeq == "\x1b[5~" && key == KEY_PAGEUP) break; 193 | if (fullSeq == "\x1b[6~" && key == KEY_PAGEDOWN) break; 194 | 195 | // Home/End 另一种序列 196 | if (fullSeq == "\x1b[1~" && key == KEY_HOME) break; 197 | if (fullSeq == "\x1b[4~" && key == KEY_END) break; 198 | } else if (ch == 'O') { // ESC O P-S 序列(F1-F4)或 ESC O H/F(Home/End) 199 | ch = getchar(); 200 | if ((ch >= 'P' && ch <= 'S') && ch == key) break; // F1-F4 201 | if (key == KEY_HOME && ch == 'H') break; // Home 202 | if (key == KEY_END && ch == 'F') break; // End 203 | } 204 | } else if (ch == key) { 205 | break; 206 | } 207 | } 208 | tcsetattr(0, TCSANOW, &oldt); 209 | } 210 | 211 | 212 | #endif 213 | 214 | } // namespace tc 215 | 216 | #endif // TC_WAIT_HPP -------------------------------------------------------------------------------- /example/19_painting_game.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 19_key_press_detection.cpp - 按键检测示例 3 | * Key Press Detection Example 4 | * 5 | * 这个示例展示了如何使用TC库的isKeyPressed函数来检测按键状态, 6 | * 并创建一个简单的交互式绘图程序。用户可以使用方向键移动光标, 7 | * 使用空格键绘制或擦除,使用ESC键退出。 8 | * 9 | * This example demonstrates how to use the TC library's isKeyPressed function 10 | * to detect key states and create a simple interactive drawing program. 11 | * Users can move the cursor with arrow keys, draw or erase with space key, 12 | * and exit with ESC key. 13 | */ 14 | 15 | #include "../include/tc.hpp" 16 | #include 17 | #include 18 | #include 19 | 20 | // 画布大小 | Canvas size 21 | const int WIDTH = 40; 22 | const int HEIGHT = 20; 23 | 24 | // 绘图符号 | Drawing symbols 25 | const char CURSOR = 'O'; 26 | const char DRAWN = '#'; 27 | const char EMPTY = ' '; 28 | 29 | // 绘图状态 | Drawing state 30 | struct DrawingState { 31 | int x = WIDTH / 2; 32 | int y = HEIGHT / 2; 33 | int prevX = WIDTH / 2; 34 | int prevY = HEIGHT / 2; 35 | std::vector canvas; 36 | bool drawing = false; 37 | bool firstDraw = true; 38 | 39 | DrawingState() { 40 | // 初始化空白画布 | Initialize empty canvas 41 | canvas.resize(HEIGHT, std::string(WIDTH, EMPTY)); 42 | } 43 | }; 44 | 45 | // 初始化绘图界面 | Initialize drawing interface 46 | void initDrawingInterface() { 47 | auto p = tc::printer(); 48 | 49 | // 隐藏光标 | Hide cursor 50 | p.hideCursor(); 51 | 52 | // 清屏并绘制初始界面 | Clear screen and draw initial interface 53 | p.clear() 54 | .println("简易绘图程序 | Simple Drawing Program") 55 | .println("使用方向键移动,空格键绘制/擦除,D键切换绘制模式,ESC键退出") 56 | .println("Use arrow keys to move, space to draw/erase, D to toggle drawing mode, ESC to exit") 57 | .println(); 58 | 59 | // 绘制顶部边框 | Draw top border 60 | p.print("+"); 61 | for (int i = 0; i < WIDTH; i++) p.print("-"); 62 | p.println("+"); 63 | 64 | // 绘制空白画布 | Draw empty canvas 65 | for (int y = 0; y < HEIGHT; y++) { 66 | p.print("|"); 67 | for (int x = 0; x < WIDTH; x++) { 68 | p.print(" "); 69 | } 70 | p.println("|"); 71 | } 72 | 73 | // 绘制底部边框 | Draw bottom border 74 | p.print("+"); 75 | for (int i = 0; i < WIDTH; i++) p.print("-"); 76 | p.println("+"); 77 | 78 | // 绘制状态行 | Draw status line 79 | p.println("位置 | Position: (0, 0) 模式 | Mode: 移动 | Moving"); 80 | } 81 | 82 | // 更新画布上的特定位置 | Update specific position on canvas 83 | void updateCanvasPosition(const DrawingState& state, int x, int y) { 84 | // 检查坐标是否在有效范围内 85 | if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) { 86 | return; // 如果坐标超出范围,直接返回,不进行任何操作 87 | } 88 | 89 | // 计算实际屏幕坐标(考虑边框和标题) | Calculate actual screen coordinates (considering borders and title) 90 | int screenX = x + 2; // +1 for border, +1 for 1-based indexing 91 | int screenY = y + 5; // +4 for title and header, +1 for 1-based indexing 92 | 93 | auto p = tc::printer(); 94 | 95 | // 调试输出当前坐标 96 | p.moveCursor(1, HEIGHT + 8); 97 | p.print("Debug - Canvas: (").print(x).print(", ").print(y).print(") Screen: (").print(screenX).print(", ").print(screenY).print(")"); 98 | 99 | p.moveCursor(screenX, screenY); 100 | 101 | if (x == state.x && y == state.y) { 102 | // 绘制光标 | Draw cursor 103 | p.print(TCOLOR_CYAN).print(CURSOR).print(TCOLOR_RESET); 104 | } else { 105 | // 绘制画布内容 | Draw canvas content 106 | if (state.canvas[y][x] == DRAWN) { 107 | p.print(TCOLOR_YELLOW).print(DRAWN).print(TCOLOR_RESET); 108 | } else { 109 | p.print(EMPTY); 110 | } 111 | } 112 | } 113 | 114 | // 更新状态信息 | Update status information 115 | void updateStatusInfo(const DrawingState& state) { 116 | auto p = tc::printer(); 117 | 118 | // 移动到状态行 | Move to status line 119 | p.moveCursor(1, HEIGHT + 7); 120 | 121 | // 清除整行 | Clear entire line 122 | p.print("\033[2K"); 123 | 124 | // 显示新状态 | Show new status 125 | p.print("位置 | Position: (") 126 | .print(state.x) 127 | .print(", ") 128 | .print(state.y) 129 | .print(") 模式 | Mode: ") 130 | .print(state.drawing ? "绘制 | Drawing" : "移动 | Moving"); 131 | } 132 | 133 | int main() { 134 | DrawingState state; 135 | bool running = true; 136 | 137 | // 初始化绘图界面 | Initialize drawing interface 138 | initDrawingInterface(); 139 | 140 | // 绘制初始光标位置 | Draw initial cursor position 141 | updateCanvasPosition(state, state.x, state.y); 142 | updateStatusInfo(state); 143 | 144 | // 主循环 | Main loop 145 | while (running) { 146 | // 检测按键 | Detect key presses 147 | if (tc::isKeyPressed(KEY_ESC)) { 148 | running = false; 149 | } 150 | 151 | // 确保画笔不接触上边界 152 | if (tc::isKeyPressed(KEY_UP) && state.y > 1) { 153 | state.prevX = state.x; 154 | state.prevY = state.y; 155 | state.y--; 156 | 157 | // 更新前一个位置和当前位置 | Update previous and current positions 158 | updateCanvasPosition(state, state.prevX, state.prevY); 159 | updateCanvasPosition(state, state.x, state.y); 160 | updateStatusInfo(state); 161 | 162 | tc::wait(0.1); // 防止移动过快 | Prevent too fast movement 163 | } 164 | 165 | // 确保画笔可以到达第20行(索引为19) 166 | if (tc::isKeyPressed(KEY_DOWN) && state.y < HEIGHT - 1) { 167 | state.prevX = state.x; 168 | state.prevY = state.y; 169 | state.y++; 170 | 171 | // 更新前一个位置和当前位置 | Update previous and current positions 172 | updateCanvasPosition(state, state.prevX, state.prevY); 173 | updateCanvasPosition(state, state.x, state.y); 174 | updateStatusInfo(state); 175 | 176 | tc::wait(0.1); 177 | } 178 | 179 | // 确保画笔不接触左边界 180 | if (tc::isKeyPressed(KEY_LEFT) && state.x > 1) { 181 | state.prevX = state.x; 182 | state.prevY = state.y; 183 | state.x--; 184 | 185 | // 更新前一个位置和当前位置 | Update previous and current positions 186 | updateCanvasPosition(state, state.prevX, state.prevY); 187 | updateCanvasPosition(state, state.x, state.y); 188 | updateStatusInfo(state); 189 | 190 | tc::wait(0.1); 191 | } 192 | 193 | // 确保画笔不接触右边界 194 | if (tc::isKeyPressed(KEY_RIGHT) && state.x < WIDTH - 2) { 195 | state.prevX = state.x; 196 | state.prevY = state.y; 197 | state.x++; 198 | 199 | // 更新前一个位置和当前位置 | Update previous and current positions 200 | updateCanvasPosition(state, state.prevX, state.prevY); 201 | updateCanvasPosition(state, state.x, state.y); 202 | updateStatusInfo(state); 203 | 204 | tc::wait(0.1); 205 | } 206 | 207 | if (tc::isKeyPressed(KEY_SPACE)) { 208 | // 切换当前位置的绘制状态 | Toggle drawing state at current position 209 | if (state.canvas[state.y][state.x] == EMPTY) { 210 | state.canvas[state.y][state.x] = DRAWN; 211 | } else { 212 | state.canvas[state.y][state.x] = EMPTY; 213 | } 214 | 215 | // 更新当前位置 | Update current position 216 | updateCanvasPosition(state, state.x, state.y); 217 | 218 | tc::wait(0.2); // 防止一次按键多次触发 | Prevent multiple triggers from one key press 219 | } 220 | 221 | // 切换绘制模式 | Toggle drawing mode 222 | if (tc::isKeyPressed('d') || tc::isKeyPressed('D')) { 223 | state.drawing = !state.drawing; 224 | updateStatusInfo(state); 225 | tc::wait(0.2); 226 | } 227 | 228 | // 如果处于绘制模式,自动在当前位置绘制 | If in drawing mode, automatically draw at current position 229 | if (state.drawing && 230 | state.y >= 0 && state.y < HEIGHT && 231 | state.x >= 0 && state.x < WIDTH && 232 | state.canvas[state.y][state.x] == EMPTY) { 233 | state.canvas[state.y][state.x] = DRAWN; 234 | updateCanvasPosition(state, state.x, state.y); 235 | } 236 | 237 | tc::wait(0.01); // 减少CPU使用率 | Reduce CPU usage 238 | } 239 | 240 | // 清屏并显示退出信息 | Clear screen and show exit message 241 | auto p = tc::printer(); 242 | p.clear() 243 | .showCursor() 244 | .println("感谢使用简易绘图程序!") 245 | .println("Thank you for using the Simple Drawing Program!"); 246 | 247 | return 0; 248 | } 249 | -------------------------------------------------------------------------------- /doc/tc_functionality.md: -------------------------------------------------------------------------------- 1 | # TC.hpp 功能文档 2 | 3 | > TC.hpp 是一个现代化的 C++17 终端控制库,支持彩色输出、字体样式、延时、进度条、终端控制等,跨平台、零依赖、纯头文件。 4 | 5 | ## 目录 6 | 7 | - [基本概述](#基本概述) 8 | - [颜色与样式](#颜色与样式) 9 | - [前景色](#前景色) 10 | - [背景色](#背景色) 11 | - [字体样式](#字体样式) 12 | - [RGB颜色](#rgb颜色) 13 | - [输出函数](#输出函数) 14 | - [标准输出](#标准输出) 15 | - [链式输出](#链式输出) 16 | - [延时与等待](#延时与等待) 17 | - [延时函数](#延时函数) 18 | - [按键等待](#按键等待) 19 | - [终端控制](#终端控制) 20 | - [光标控制](#光标控制) 21 | - [终端尺寸](#终端尺寸) 22 | - [清屏功能](#清屏功能) 23 | - [进度条](#进度条) 24 | - [系统相关API](#系统相关api) 25 | - [系统时间](#系统时间) 26 | - [系统命令](#系统命令) 27 | - [系统检测](#系统检测) 28 | - [跨平台兼容性](#跨平台兼容性) 29 | - [使用示例](#使用示例) 30 | 31 | ## 基本概述 32 | 33 | TC.hpp 是一个跨平台的终端控制库,提供了丰富的终端操作功能,包括颜色输出、字体样式、光标控制、延时等。该库采用纯头文件设计,无需额外依赖,只需包含 `tc.hpp` 即可使用所有功能。 34 | 35 | 主要特点: 36 | - 跨平台支持(Windows、Linux、macOS) 37 | - 纯头文件,零依赖 38 | - 现代 C++17 设计 39 | - 丰富的终端控制功能 40 | - 简洁易用的 API 41 | 42 | ## 颜色与样式 43 | 44 | ### 前景色 45 | 46 | TC.hpp 提供了一系列前景色宏,可直接在代码中使用: 47 | 48 | | 宏名 | 颜色 | ANSI代码 | 49 | |------|------|----------| 50 | | `TCOLOR_BLACK` | 黑色 | `\033[30m` | 51 | | `TCOLOR_RED` | 红色 | `\033[31m` | 52 | | `TCOLOR_GREEN` | 绿色 | `\033[32m` | 53 | | `TCOLOR_YELLOW` | 黄色 | `\033[33m` | 54 | | `TCOLOR_BLUE` | 蓝色 | `\033[34m` | 55 | | `TCOLOR_MAGENTA` | 洋红 | `\033[35m` | 56 | | `TCOLOR_CYAN` | 青色 | `\033[36m` | 57 | | `TCOLOR_WHITE` | 白色 | `\033[37m` | 58 | | `TCOLOR_DEFAULT` | 默认 | `\033[39m` | 59 | | `TCOLOR_RESET` | 重置 | `\033[0m` | 60 | 61 | 使用示例: 62 | ```cpp 63 | tc::println(TCOLOR_RED, "这是红色文本", TCOLOR_RESET); 64 | ``` 65 | 66 | ### 背景色 67 | 68 | 背景色宏可以设置文本的背景颜色: 69 | 70 | | 宏名 | 颜色 | ANSI代码 | 71 | |------|------|----------| 72 | | `BCOLOR_BLACK` | 黑色 | `\033[40m` | 73 | | `BCOLOR_RED` | 红色 | `\033[41m` | 74 | | `BCOLOR_GREEN` | 绿色 | `\033[42m` | 75 | | `BCOLOR_YELLOW` | 黄色 | `\033[43m` | 76 | | `BCOLOR_BLUE` | 蓝色 | `\033[44m` | 77 | | `BCOLOR_MAGENTA` | 洋红 | `\033[45m` | 78 | | `BCOLOR_CYAN` | 青色 | `\033[46m` | 79 | | `BCOLOR_WHITE` | 白色 | `\033[47m` | 80 | | `BCOLOR_DEFAULT` | 默认 | `\033[49m` | 81 | 82 | 使用示例: 83 | ```cpp 84 | tc::println(TCOLOR_BLACK, BCOLOR_YELLOW, "黑字黄底", TCOLOR_RESET); 85 | ``` 86 | 87 | ### 字体样式 88 | 89 | TC.hpp 支持多种字体样式: 90 | 91 | | 宏名 | 效果 | ANSI代码 | 兼容性 | 92 | |------|------|----------|--------| 93 | | `TFONT_BOLD` | 粗体/加粗 | `\033[1m` | Windows完全支持,其他终端大多支持 | 94 | | `TFONT_FAINT` | 微弱/淡色 | `\033[2m` | Windows完全支持,其他终端部分支持 | 95 | | `TFONT_ITALIC` | 斜体 | `\033[3m` | Windows完全支持,其他终端部分支持 | 96 | | `TFONT_UNDERLINE` | 下划线 | `\033[4m` | Windows完全支持,其他终端大多支持 | 97 | | `TFONT_BLINK_SLOW` | 慢速闪烁 | `\033[5m` | Windows完全支持,其他终端部分支持 | 98 | | `TFONT_BLINK_FAST` | 快速闪烁 | `\033[6m` | Windows完全支持,其他终端很少支持 | 99 | | `TFONT_REVERSE` | 反色 | `\033[7m` | Windows完全支持,其他终端大多支持 | 100 | | `TFONT_CONCEAL` | 隐藏 | `\033[8m` | Windows完全支持,其他终端很少支持 | 101 | | `TFONT_CROSSED` | 删除线 | `\033[9m` | Windows完全支持,其他终端部分支持 | 102 | | `TFONT_RESET` | 全部重置 | `\033[0m` | Windows完全支持,其他终端大多支持 | 103 | 104 | 使用示例: 105 | ```cpp 106 | tc::println(TFONT_BOLD, "粗体文本", TFONT_RESET); 107 | tc::println(TFONT_UNDERLINE, "下划线文本", TFONT_RESET); 108 | ``` 109 | 110 | ### RGB颜色 111 | 112 | TC.hpp 支持 RGB 颜色设置: 113 | 114 | ```cpp 115 | tc::println(TCOLOR_RGB(255, 0, 0), "自定义红色", TCOLOR_RESET); 116 | ``` 117 | 118 | ## 输出函数 119 | 120 | ### 标准输出 121 | 122 | TC.hpp 提供了类似 Python 的 print/println 函数: 123 | 124 | ```cpp 125 | // 多参数打印 126 | tc::print("Hello", " ", "World"); // 输出: Hello World 127 | tc::println("Hello", " ", "World"); // 输出: Hello World 并换行 128 | 129 | // 带颜色的打印 130 | tc::println(TCOLOR_GREEN, "绿色文本", TCOLOR_RESET); 131 | ``` 132 | 133 | ### 链式输出 134 | 135 | TC.hpp 提供了流式输出接口: 136 | 137 | ```cpp 138 | // 流式输出 139 | tc::tout << TCOLOR_BLUE << "蓝色文本" << TCOLOR_RESET << std::endl; 140 | 141 | // 链式 Printer API 142 | tc::printer() 143 | .moveCursor(10, 5) 144 | .print("在位置(10,5)打印") 145 | .moveCursor(10, 6) 146 | .println("下一行"); 147 | ``` 148 | 149 | ## 延时与等待 150 | 151 | ### 延时函数 152 | 153 | TC.hpp 提供了多种延时函数: 154 | 155 | ```cpp 156 | // 等待指定秒数(支持小数) 157 | tc::wait(1.5); // 等待1.5秒 158 | 159 | // 等待指定毫秒 160 | tc::tsleep(1000); // 等待1000毫秒 161 | 162 | // 流式延时 163 | tc::tout << "等待前" << tc::tsleep(500) << "等待后" << std::endl; 164 | 165 | // 延时流 166 | tc::tsleep_stream << 1000; // 等待1000毫秒 167 | ``` 168 | 169 | ### 按键等待 170 | 171 | TC.hpp 提供了等待按键的功能: 172 | 173 | ```cpp 174 | // 等待任意按键 175 | tc::waitKey(); 176 | 177 | // 等待特定按键 178 | tc::waitKey('A'); // 等待按下A键 179 | tc::waitKey(KEY_ESC); // 等待按下ESC键 180 | ``` 181 | 182 | 常用特殊按键宏: 183 | 184 | | 宏名 | 按键 | 185 | |------|------| 186 | | `KEY_ESC` | ESC键 | 187 | | `KEY_SPACE` | 空格键 | 188 | | `KEY_ENTER` | 回车键 | 189 | | `KEY_TAB` | Tab键 | 190 | | `KEY_BACKSPACE` | 退格键 | 191 | | `KEY_UP` | 上方向键 | 192 | | `KEY_DOWN` | 下方向键 | 193 | | `KEY_LEFT` | 左方向键 | 194 | | `KEY_RIGHT` | 右方向键 | 195 | | `KEY_F1` ~ `KEY_F12` | F1-F12功能键 | 196 | 197 | ## 终端控制 198 | 199 | ### 光标控制 200 | 201 | TC.hpp 提供了光标控制功能: 202 | 203 | ```cpp 204 | // 移动光标到指定位置 205 | tc::printer().moveCursor(10, 5); // 移动到第5行,第10列 206 | 207 | // 隐藏/显示光标 208 | tc::printer().hideCursor(); 209 | tc::printer().showCursor(); 210 | 211 | // 相对移动光标 212 | tc::printer().moveCursor(tc::Printer::Direction::Up, 2); // 上移2行 213 | tc::printer().moveCursor(tc::Printer::Direction::Right, 5); // 右移5列 214 | ``` 215 | 216 | ### 终端尺寸 217 | 218 | 获取终端窗口大小: 219 | 220 | ```cpp 221 | auto size = tc::printer().getSize(); 222 | tc::println("终端大小: ", size.first, "x", size.second); // 宽x高 223 | ``` 224 | 225 | ### 清屏功能 226 | 227 | 清除终端内容: 228 | 229 | ```cpp 230 | tc::printer().clear(); // 清屏并将光标移到左上角 231 | ``` 232 | 233 | ## 进度条 234 | 235 | TC.hpp 提供了简单易用的进度条功能: 236 | 237 | ```cpp 238 | // 创建进度条(宽度30,填充字符"█",未填充字符"░",绿色) 239 | tc::ProgressBar bar(30, "█", "░", TCOLOR_GREEN); 240 | 241 | // 显示进度(0.0-1.0之间) 242 | for (int i = 0; i <= 100; ++i) { 243 | bar.show(i / 100.0, "处理中..."); 244 | tc::wait(0.02); // 模拟处理时间 245 | } 246 | 247 | // 完成进度条 248 | bar.finish("完成!"); 249 | ``` 250 | 251 | ## 系统相关API 252 | 253 | ### 系统时间 254 | 255 | TC.hpp 提供了获取系统时间的功能: 256 | 257 | ```cpp 258 | // 获取当前年份 259 | int year = tc::getSystemTime(SYS_YEAR); 260 | 261 | // 获取当前月份 262 | int month = tc::getSystemTime(SYS_MONTH); 263 | 264 | // 获取Unix时间戳 265 | int timestamp = tc::getSystemTime(); // 默认返回时间戳 266 | ``` 267 | 268 | 时间宏定义: 269 | 270 | | 宏名 | 返回值 | 271 | |------|--------| 272 | | `SYS_YEAR` | 年份 | 273 | | `SYS_MONTH` | 月份(1-12) | 274 | | `SYS_DAY` | 日期(1-31) | 275 | | `SYS_HOUR` | 小时(0-23) | 276 | | `SYS_MINUTE` | 分钟(0-59) | 277 | | `SYS_SECOND` | 秒(0-59) | 278 | | `SYS_TIMESTAMP` | Unix时间戳 | 279 | 280 | ### 系统命令 281 | 282 | 执行系统命令: 283 | 284 | ```cpp 285 | // 执行系统命令 286 | tc::systemConsole("echo Hello World"); 287 | ``` 288 | 289 | ### 系统检测 290 | 291 | TC.hpp 提供了检测当前操作系统的功能: 292 | 293 | ```cpp 294 | // 获取当前操作系统类型 295 | int os = tc::systemCheck(); 296 | 297 | // 根据返回值判断系统类型 298 | switch (os) { 299 | case OS_WINDOWSNT11: 300 | tc::println("Windows 11"); 301 | break; 302 | case OS_LINUX: 303 | tc::println("Linux"); 304 | break; 305 | // 其他系统类型... 306 | } 307 | ``` 308 | 309 | 主要系统类型宏: 310 | 311 | | 宏名 | 系统类型 | 312 | |------|----------| 313 | | `OS_WINDOWSNT11` | Windows 11 | 314 | | `OS_WINDOWSNT10` | Windows 10 | 315 | | `OS_WINDOWSNT6` | Windows Vista/7/8/8.1 | 316 | | `OS_LINUX` | Linux | 317 | | `OS_ANDROID` | Android | 318 | | `OS_MACOS` | macOS | 319 | | `OS_IOS` | iOS | 320 | | `OS_BSD` | BSD | 321 | | `OS_UNIX` | Unix-like | 322 | 323 | ## 跨平台兼容性 324 | 325 | TC.hpp 在不同平台上的实现方式: 326 | 327 | - **Windows**: 使用 Windows Console API(Win32 API)实现终端控制功能,不使用ANSI转义序列 328 | - **Linux/macOS**: 使用 ANSI 转义序列和 POSIX API 329 | 330 | 库会自动检测平台并使用适当的实现,无需用户手动配置。所有颜色、字体样式和终端控制功能在Windows平台上都能完全支持,因为它们直接使用了原生的Win32 API,而不依赖于终端对ANSI转义序列的支持。 331 | 332 | ## 使用示例 333 | 334 | 完整示例程序: 335 | 336 | ```cpp 337 | #include "tc.hpp" 338 | 339 | int main() { 340 | // 清屏 341 | tc::printer().clear(); 342 | 343 | // 标题 344 | tc::println(TCOLOR_CYAN, TFONT_BOLD, "TC.hpp 功能演示", TCOLOR_RESET); 345 | tc::println(); 346 | 347 | // 颜色演示 348 | tc::println("=== 颜色演示 ==="); 349 | tc::println(TCOLOR_RED, "红色文本", TCOLOR_RESET); 350 | tc::println(TCOLOR_GREEN, "绿色文本", TCOLOR_RESET); 351 | tc::println(TCOLOR_BLUE, "蓝色文本", TCOLOR_RESET); 352 | tc::println(TCOLOR_YELLOW, BCOLOR_BLUE, "黄字蓝底", TCOLOR_RESET); 353 | tc::println(TCOLOR_RGB(255, 128, 0), "自定义橙色", TCOLOR_RESET); 354 | tc::println(); 355 | 356 | // 字体样式演示 357 | tc::println("=== 字体样式演示 ==="); 358 | tc::println(TFONT_BOLD, "粗体文本", TCOLOR_RESET); 359 | tc::println(TFONT_UNDERLINE, "下划线文本", TCOLOR_RESET); 360 | tc::println(TFONT_ITALIC, "斜体文本", TCOLOR_RESET); 361 | tc::println(TFONT_CROSSED, "删除线文本", TCOLOR_RESET); 362 | tc::println(); 363 | 364 | // 进度条演示 365 | tc::println("=== 进度条演示 ==="); 366 | tc::ProgressBar bar(30, "█", "░", TCOLOR_GREEN); 367 | for (int i = 0; i <= 100; i += 10) { 368 | bar.show(i / 100.0, "处理中..."); 369 | tc::wait(0.2); 370 | } 371 | bar.finish("完成!"); 372 | tc::println(); 373 | 374 | // 系统信息演示 375 | tc::println("=== 系统信息 ==="); 376 | int year = tc::getSystemTime(SYS_YEAR); 377 | int month = tc::getSystemTime(SYS_MONTH); 378 | int day = tc::getSystemTime(SYS_DAY); 379 | tc::println("当前日期: ", year, "-", month, "-", day); 380 | 381 | int os = tc::systemCheck(); 382 | tc::print("当前系统: "); 383 | switch (os) { 384 | case OS_WINDOWSNT11: tc::println("Windows 11"); break; 385 | case OS_WINDOWSNT10: tc::println("Windows 10"); break; 386 | case OS_LINUX: tc::println("Linux"); break; 387 | case OS_MACOS: tc::println("macOS"); break; 388 | default: tc::println("其他系统"); 389 | } 390 | 391 | tc::println("\n按任意键退出..."); 392 | tc::waitKey(); 393 | 394 | return 0; 395 | } 396 | ``` 397 | 398 | --- 399 | 400 | 本文档提供了 TC.hpp 库的主要功能概述。更多详细信息和高级用法,请参考源代码中的注释和示例。 -------------------------------------------------------------------------------- /example/16_snake_game.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/tc.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef _WIN32 10 | #include 11 | #else 12 | #include 13 | #include 14 | #include 15 | #endif 16 | 17 | // 跨平台按键检测 18 | inline int kbhit() { 19 | #ifdef _WIN32 20 | return _kbhit(); 21 | #else 22 | struct termios oldt, newt; 23 | int ch; 24 | int oldf; 25 | 26 | tcgetattr(STDIN_FILENO, &oldt); 27 | newt = oldt; 28 | newt.c_lflag &= ~(ICANON | ECHO); 29 | tcsetattr(STDIN_FILENO, TCSANOW, &newt); 30 | oldf = fcntl(STDIN_FILENO, F_GETFL, 0); 31 | fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); 32 | 33 | ch = getchar(); 34 | 35 | tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 36 | fcntl(STDIN_FILENO, F_SETFL, oldf); 37 | 38 | if(ch != EOF) { 39 | ungetc(ch, stdin); 40 | return 1; 41 | } 42 | return 0; 43 | #endif 44 | } 45 | 46 | inline int getch() { 47 | #ifdef _WIN32 48 | return _getch(); 49 | #else 50 | int ch; 51 | struct termios oldt, newt; 52 | 53 | tcgetattr(STDIN_FILENO, &oldt); 54 | newt = oldt; 55 | newt.c_lflag &= ~(ICANON | ECHO); 56 | tcsetattr(STDIN_FILENO, TCSANOW, &newt); 57 | 58 | ch = getchar(); 59 | 60 | tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 61 | return ch; 62 | #endif 63 | } 64 | 65 | // 简单的贪吃蛇游戏 66 | class SnakeGame { 67 | private: 68 | int width_, height_; 69 | int score_ = 0; 70 | bool gameOver_ = false; 71 | 72 | // 蛇的方向 73 | enum class Direction { UP, DOWN, LEFT, RIGHT }; 74 | Direction dir_ = Direction::RIGHT; 75 | 76 | // 蛇身和食物位置 77 | struct Point { 78 | int x, y; 79 | bool operator==(const Point& other) const { 80 | return x == other.x && y == other.y; 81 | } 82 | }; 83 | 84 | std::vector snake_; 85 | Point last_tail_{-1, -1}; 86 | Point food_; 87 | std::mt19937 rng_; 88 | 89 | // 生成随机食物 90 | void generateFood() { 91 | std::uniform_int_distribution distX(2, width_ - 2); 92 | std::uniform_int_distribution distY(2, height_ - 2); 93 | 94 | food_ = {distX(rng_), distY(rng_)}; 95 | 96 | // 确保食物不在蛇身上 97 | while (std::find(snake_.begin(), snake_.end(), food_) != snake_.end()) { 98 | food_ = {distX(rng_), distY(rng_)}; 99 | } 100 | } 101 | 102 | // 绘制游戏界面 103 | void draw() { 104 | tc::printer().moveCursor(0, 0); 105 | 106 | // 绘制上边界 107 | for (int x = 0; x < width_; ++x) { 108 | tc::printer().moveCursor(x, 0); 109 | tc::print(TCOLOR_CYAN, "#", TCOLOR_RESET); 110 | } 111 | 112 | // 绘制下边界 113 | for (int x = 0; x < width_; ++x) { 114 | tc::printer().moveCursor(x, height_ - 1); 115 | tc::print(TCOLOR_CYAN, "#", TCOLOR_RESET); 116 | } 117 | 118 | // 绘制左右边界 119 | for (int y = 0; y < height_; ++y) { 120 | tc::printer().moveCursor(0, y); 121 | tc::print(TCOLOR_CYAN, "#", TCOLOR_RESET); 122 | tc::printer().moveCursor(width_ - 1, y); 123 | tc::print(TCOLOR_CYAN, "#", TCOLOR_RESET); 124 | } 125 | 126 | //清除旧的尾巴 127 | if(last_tail_.x != -1 && last_tail_.y != -1){ 128 | tc::printer().moveCursor(last_tail_.x, last_tail_.y); 129 | tc::print(" ", TCOLOR_RESET); 130 | }else{ 131 | tc::printer().moveCursor(snake_.back().x, snake_.back().y); 132 | tc::print(" ", TCOLOR_RESET); 133 | } 134 | 135 | // 绘制蛇 136 | for (const auto& p : snake_) { 137 | tc::printer().moveCursor(p.x, p.y); 138 | tc::print(TCOLOR_GREEN, "O", TCOLOR_RESET); 139 | } 140 | 141 | // 绘制蛇头 142 | tc::printer().moveCursor(snake_.front().x, snake_.front().y); 143 | tc::print(TCOLOR_YELLOW, "@", TCOLOR_RESET); 144 | 145 | // 绘制食物 146 | tc::printer().moveCursor(food_.x, food_.y); 147 | tc::print(TCOLOR_RED, "*", TCOLOR_RESET); 148 | 149 | // 绘制分数 150 | tc::printer().moveCursor(width_ + 2, 1); 151 | tc::println(TCOLOR_CYAN, "贪吃蛇游戏", TCOLOR_RESET); 152 | tc::printer().moveCursor(width_ + 2, 3); 153 | tc::println(TCOLOR_YELLOW, "分数: ", score_, TCOLOR_RESET); 154 | tc::printer().moveCursor(width_ + 2, 5); 155 | tc::println("方向键: 移动"); 156 | tc::printer().moveCursor(width_ + 2, 6); 157 | tc::println("ESC键: 退出"); 158 | 159 | // 如果游戏结束,显示提示 160 | if (gameOver_) { 161 | tc::printer().moveCursor(width_ / 2 - 5, height_ / 2); 162 | tc::println(TCOLOR_RED, TFONT_BOLD, "游戏结束!", TCOLOR_RESET); 163 | tc::printer().moveCursor(width_ / 2 - 10, height_ / 2 + 1); 164 | tc::println(TCOLOR_YELLOW, "按任意键退出...", TCOLOR_RESET); 165 | } 166 | } 167 | 168 | // 处理输入 169 | void handleInput() { 170 | if (kbhit()) { 171 | int key = getch(); 172 | #ifdef _WIN32 173 | if (key == 224) { // 方向键前缀 174 | key = getch(); 175 | switch (key) { 176 | case 72: // 上 177 | if (dir_ != Direction::DOWN) dir_ = Direction::UP; 178 | break; 179 | case 80: // 下 180 | if (dir_ != Direction::UP) dir_ = Direction::DOWN; 181 | break; 182 | case 75: // 左 183 | if (dir_ != Direction::RIGHT) dir_ = Direction::LEFT; 184 | break; 185 | case 77: // 右 186 | if (dir_ != Direction::LEFT) dir_ = Direction::RIGHT; 187 | break; 188 | } 189 | } 190 | #else 191 | if (key == 27) { // ESC 序列开始 192 | if (getch() == '[') { 193 | key = getch(); 194 | switch (key) { 195 | case 'A': // 上 196 | if (dir_ != Direction::DOWN) dir_ = Direction::UP; 197 | break; 198 | case 'B': // 下 199 | if (dir_ != Direction::UP) dir_ = Direction::DOWN; 200 | break; 201 | case 'D': // 左 202 | if (dir_ != Direction::RIGHT) dir_ = Direction::LEFT; 203 | break; 204 | case 'C': // 右 205 | if (dir_ != Direction::LEFT) dir_ = Direction::RIGHT; 206 | break; 207 | } 208 | } 209 | } 210 | #endif 211 | if (key == 27) { // ESC 键 212 | gameOver_ = true; 213 | } 214 | } 215 | } 216 | 217 | // 更新游戏状态 218 | void update() { 219 | if (gameOver_) return; 220 | 221 | // 根据方向移动蛇头 222 | Point newHead = snake_.front(); 223 | switch (dir_) { 224 | case Direction::UP: 225 | newHead.y--; 226 | break; 227 | case Direction::DOWN: 228 | newHead.y++; 229 | break; 230 | case Direction::LEFT: 231 | newHead.x--; 232 | break; 233 | case Direction::RIGHT: 234 | newHead.x++; 235 | break; 236 | } 237 | 238 | // 检查是否撞墙 239 | if (newHead.x <= 1 || newHead.x >= width_ - 1 || 240 | newHead.y <= 1 || newHead.y >= height_ - 1) { 241 | gameOver_ = true; 242 | return; 243 | } 244 | 245 | // 检查是否撞到自己 246 | for (const auto& segment : snake_) { 247 | if (newHead == segment) { 248 | gameOver_ = true; 249 | return; 250 | } 251 | } 252 | 253 | // 移动蛇 254 | snake_.insert(snake_.begin(), newHead); 255 | 256 | // 检查是否吃到食物 257 | if (newHead == food_) { 258 | score_ += 10; 259 | last_tail_ = {-1, -1}; 260 | generateFood(); 261 | } else { 262 | last_tail_ = snake_.back(); 263 | snake_.pop_back(); // 如果没吃到食物,移除尾部 264 | } 265 | } 266 | 267 | public: 268 | SnakeGame(int width = 30, int height = 20) 269 | : width_(width), height_(height), rng_(std::random_device()()) { 270 | // 初始化蛇 271 | snake_.push_back({width_ / 2, height_ / 2}); 272 | snake_.push_back({width_ / 2 - 1, height_ / 2}); 273 | snake_.push_back({width_ / 2 - 2, height_ / 2}); 274 | 275 | // 生成第一个食物 276 | generateFood(); 277 | } 278 | 279 | void run() { 280 | tc::printer().hideCursor(); 281 | tc::printer().clear(); 282 | 283 | while (!gameOver_) { 284 | handleInput(); 285 | update(); 286 | draw(); 287 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 288 | } 289 | 290 | draw(); // 最后一次绘制,显示游戏结束 291 | tc::printer().showCursor(); 292 | tc::waitKey(); // 等待按键退出 293 | } 294 | }; 295 | 296 | int main() { 297 | tc::printer().clear(); 298 | tc::println(TCOLOR_CYAN, TFONT_BOLD, "贪吃蛇游戏", TCOLOR_RESET); 299 | tc::println(TCOLOR_CYAN, "==========", TCOLOR_RESET); 300 | tc::println(); 301 | tc::println("使用方向键控制蛇的移动,按ESC键退出游戏。"); 302 | tc::println("按任意键开始游戏..."); 303 | tc::waitKey(); 304 | 305 | SnakeGame game; 306 | game.run(); 307 | 308 | tc::terminal::clear(); 309 | return 0; 310 | } -------------------------------------------------------------------------------- /include/tc_terminal.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tc_terminal.hpp - TC库终端控制模块 3 | * TC Terminal Control Module 4 | * 5 | * 这个文件包含了TC库中所有与终端控制相关的功能,包括: 6 | * - Printer类,提供链式终端控制接口 7 | * - 终端清屏、光标移动、尺寸获取 8 | * - 跨平台终端操作支持 9 | * - terminal命名空间的便利函数 10 | * 11 | * This file contains all terminal control related functionality in the TC library, including: 12 | * - Printer class providing chainable terminal control interface 13 | * - Terminal clearing, cursor movement, size retrieval 14 | * - Cross-platform terminal operation support 15 | * - Convenient functions in terminal namespace 16 | * 17 | * 版本 Version: 1.1.1 18 | * 作者 Author: 537 Studio 19 | * 许可 License: MIT 20 | */ 21 | 22 | #ifndef TC_TERMINAL_HPP 23 | #define TC_TERMINAL_HPP 24 | 25 | // 标准库包含 | Standard library includes 26 | #include // 输入输出流 | Input/output streams 27 | #include // 实用工具,如std::pair | Utility tools like std::pair 28 | #include // 类型特征 | Type traits 29 | #include // C字符串操作 | C string operations 30 | #include // C++字符串 | C++ string 31 | 32 | // 平台特定包含 | Platform-specific includes 33 | #ifdef _WIN32 34 | #include // Windows API 35 | #include "tc_colors.hpp" // TC颜色模块 | TC color module 36 | #else 37 | #include // 系统输入输出控制 | System I/O control 38 | #include // POSIX API 39 | #endif 40 | 41 | namespace tc { 42 | 43 | /** 44 | * Printer类 - 提供终端控制和打印功能的链式接口 45 | * Printer class - Provides a chainable interface for terminal control and printing 46 | * 47 | * 这个类封装了终端控制操作,如清屏、移动光标、显示/隐藏光标等, 48 | * 并提供链式调用接口,使得多个操作可以连续执行。 49 | * 50 | * This class encapsulates terminal control operations such as clearing screen, 51 | * moving cursor, showing/hiding cursor, etc., and provides a chainable interface 52 | * allowing multiple operations to be executed in sequence. 53 | */ 54 | class Printer { 55 | public: 56 | /** 57 | * flush函数 - 刷新终端输出缓冲区 58 | * flush function - Flushes the terminal output buffer 59 | * 60 | * @return Printer对象的引用,支持链式调用 | Reference to Printer object for chaining 61 | */ 62 | Printer& flush() { 63 | std::cout.flush(); 64 | return *this; 65 | } 66 | /** 67 | * 清屏并将光标移动到左上角 68 | * Clear screen and move cursor to top-left corner 69 | * 70 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 71 | */ 72 | Printer& clear() { 73 | std::cout << "\033[2J\033[H"; // ANSI清屏和光标定位序列 | ANSI clear screen and cursor positioning sequence 74 | return *this; 75 | } 76 | 77 | /** 78 | * 将光标移动到指定坐标 79 | * Move cursor to specified coordinates 80 | * 81 | * @param x 列坐标(从1开始) | Column coordinate (1-based) 82 | * @param y 行坐标(从1开始) | Row coordinate (1-based) 83 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 84 | */ 85 | Printer& moveCursor(int x, int y) { 86 | std::cout << "\033[" << y << ";" << x << "H"; // ANSI光标定位序列 | ANSI cursor positioning sequence 87 | return *this; 88 | } 89 | 90 | /** 91 | * 无参数打印函数 92 | * No-argument print function 93 | * 94 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 95 | */ 96 | Printer& print() { return *this; } 97 | 98 | /** 99 | * 可变参数打印函数 100 | * Variadic print function 101 | * 102 | * @param args 要打印的参数 | Arguments to print 103 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 104 | */ 105 | template 106 | Printer& print(Args&&... args) { 107 | bool needsFlush = false; 108 | auto check = [&needsFlush](const auto& arg) { 109 | using T = std::decay_t; 110 | if constexpr (std::is_same_v || std::is_same_v) { 111 | needsFlush |= (std::strchr(arg, '\r') != nullptr); 112 | } else if constexpr (std::is_same_v) { 113 | needsFlush |= (arg.find('\r') != std::string::npos); 114 | } else if constexpr (std::is_same_v) { 115 | needsFlush |= (arg == '\r'); 116 | } 117 | }; 118 | (check(std::forward(args)), ...); 119 | 120 | (void)std::initializer_list{(std::cout << std::forward(args), 0)...}; 121 | if (needsFlush) { 122 | flush(); 123 | } 124 | return *this; 125 | } 126 | 127 | /** 128 | * 可变参数打印函数,带换行 129 | * Variadic print function with newline 130 | * 131 | * @param args 要打印的参数 | Arguments to print 132 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 133 | */ 134 | template 135 | Printer& println(Args&&... args) { 136 | (void)std::initializer_list{(std::cout << std::forward(args), 0)...}; 137 | std::cout << std::endl; // endl 自带 flush 138 | return *this; 139 | } 140 | 141 | /** 142 | * 隐藏光标 143 | * Hide cursor 144 | * 145 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 146 | */ 147 | Printer& hideCursor() { 148 | std::cout << "\033[?25l"; // ANSI隐藏光标序列 | ANSI hide cursor sequence 149 | flush(); // 立即刷新以确保光标状态更新 150 | return *this; 151 | } 152 | 153 | /** 154 | * 显示光标 155 | * Show cursor 156 | * 157 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 158 | */ 159 | Printer& showCursor() { 160 | std::cout << "\033[?25h"; // ANSI显示光标序列 | ANSI show cursor sequence 161 | flush(); // 立即刷新以确保光标状态更新 162 | return *this; 163 | } 164 | 165 | /** 166 | * 光标移动方向枚举 167 | * Cursor movement direction enum 168 | */ 169 | enum class Direction { 170 | Up, // 向上 | Upward 171 | Down, // 向下 | Downward 172 | Left, // 向左 | Leftward 173 | Right // 向右 | Rightward 174 | }; 175 | 176 | /** 177 | * 按指定方向移动光标 178 | * Move cursor in specified direction 179 | * 180 | * @param dir 移动方向 | Movement direction 181 | * @param n 移动步数 | Number of steps to move 182 | * @return 对象自身引用,支持链式调用 | Self reference for chaining 183 | */ 184 | Printer& moveCursor(Direction dir, int n) { 185 | switch(dir) { 186 | case Direction::Up: std::cout << "\033[" << n << "A"; break; // 向上移动 | Move up 187 | case Direction::Down: std::cout << "\033[" << n << "B"; break; // 向下移动 | Move down 188 | case Direction::Right: std::cout << "\033[" << n << "C"; break; // 向右移动 | Move right 189 | case Direction::Left: std::cout << "\033[" << n << "D"; break; // 向左移动 | Move left 190 | } 191 | return *this; 192 | } 193 | 194 | /** 195 | * 获取终端窗口大小 196 | * Get terminal window size 197 | * 198 | * @return 包含宽度和高度的对组 | Pair containing width and height 199 | */ 200 | std::pair getSize() { 201 | #ifdef _WIN32 202 | // Windows平台实现 | Windows platform implementation 203 | CONSOLE_SCREEN_BUFFER_INFO csbi; 204 | int cols = 80, rows = 25; // 默认值 | Default values 205 | HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); 206 | if (GetConsoleScreenBufferInfo(h, &csbi)) { 207 | // 计算实际窗口大小 | Calculate actual window size 208 | cols = csbi.srWindow.Right - csbi.srWindow.Left + 1; 209 | rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; 210 | } 211 | return {cols, rows}; 212 | #else 213 | // Unix/Linux/macOS平台实现 | Unix/Linux/macOS platform implementation 214 | struct winsize size; 215 | if (ioctl(1, TIOCGWINSZ, &size) == 0) 216 | return {size.ws_col, size.ws_row}; 217 | return {80, 25}; // 默认值 | Default values 218 | #endif 219 | } 220 | }; 221 | 222 | /** 223 | * 创建并返回一个Printer对象 224 | * Create and return a Printer object 225 | * 226 | * @return 新的Printer对象 | New Printer object 227 | */ 228 | inline Printer printer() { return Printer(); } 229 | 230 | /** 231 | * 终端控制函数命名空间 232 | * Terminal control functions namespace 233 | * 234 | * 这个命名空间提供了一组用于控制终端的函数,如清屏、移动光标、获取终端尺寸和刷新输出缓冲区。 235 | * 这些函数在不同平台上使用相应的实现,提供统一的接口。 236 | * 237 | * This namespace provides a set of functions for terminal control, such as clearing the screen, 238 | * moving the cursor, getting terminal size, and flushing output buffer. These functions use 239 | * the appropriate implementation on different platforms, providing a unified interface. 240 | */ 241 | namespace terminal { 242 | /** 243 | * 刷新终端输出缓冲区 244 | * Flush terminal output buffer 245 | * 246 | * 确保所有待输出的内容立即显示在终端上。在动画效果、实时更新或需要立即显示的场景下特别有用。 247 | * Ensures all pending output is immediately displayed on the terminal. 248 | * Particularly useful for animations, real-time updates, or when immediate display is required. 249 | */ 250 | inline void flush() { 251 | std::cout.flush(); 252 | } 253 | /** 254 | * 清空终端屏幕 255 | * Clear terminal screen 256 | * 257 | * 清除终端中的所有内容并将光标移动到左上角。 258 | * Clears all content in the terminal and moves the cursor to the top-left corner. 259 | */ 260 | inline void clear() { 261 | #ifdef _WIN32 262 | // Windows平台实现 | Windows platform implementation 263 | Win32Console::getInstance().clearScreen(); 264 | #else 265 | // 非Windows平台实现 | Non-Windows platform implementation 266 | std::cout << "\033[2J\033[H"; // ANSI清屏序列 | ANSI clear screen sequence 267 | #endif 268 | } 269 | 270 | /** 271 | * 移动光标到指定位置 272 | * Move cursor to specified position 273 | * 274 | * @param x 列坐标(从1开始) | Column coordinate (1-based) 275 | * @param y 行坐标(从1开始) | Row coordinate (1-based) 276 | */ 277 | inline void moveCursor(int x, int y) { 278 | #ifdef _WIN32 279 | // Windows平台实现 | Windows platform implementation 280 | Win32Console::getInstance().moveCursor(x - 1, y - 1); // Win32API是0基索引 | Win32 API is 0-based 281 | #else 282 | // 非Windows平台实现 | Non-Windows platform implementation 283 | std::cout << "\033[" << y << ";" << x << "H"; // ANSI光标定位序列 | ANSI cursor positioning sequence 284 | #endif 285 | } 286 | 287 | /** 288 | * 获取终端窗口大小 289 | * Get terminal window size 290 | * 291 | * @return 包含宽度和高度的对组 | Pair containing width and height 292 | */ 293 | inline std::pair getSize() { 294 | #ifdef _WIN32 295 | // Windows平台实现 | Windows platform implementation 296 | return Win32Console::getInstance().getConsoleSize(); 297 | #else 298 | // 非Windows平台实现 | Non-Windows platform implementation 299 | struct winsize w; 300 | ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); 301 | return {w.ws_col, w.ws_row}; 302 | #endif 303 | } 304 | } 305 | 306 | } // namespace tc 307 | 308 | #endif // TC_TERMINAL_HPP -------------------------------------------------------------------------------- /doc/tc_updated_functionality.md: -------------------------------------------------------------------------------- 1 | # TC.hpp 功能文档(更新版) 2 | 3 | > TC.hpp 是一个现代化的 C++17 终端控制库,支持彩色输出、字体样式、延时、进度条、终端控制等,跨平台、零依赖、纯头文件。 4 | 5 | ## 目录 6 | 7 | - [基本概述](#基本概述) 8 | - [颜色与样式](#颜色与样式) 9 | - [前景色](#前景色) 10 | - [背景色](#背景色) 11 | - [字体样式](#字体样式) 12 | - [RGB颜色](#rgb颜色) 13 | - [输出函数](#输出函数) 14 | - [标准输出](#标准输出) 15 | - [链式输出](#链式输出) 16 | - [延时与等待](#延时与等待) 17 | - [延时函数](#延时函数) 18 | - [按键等待](#按键等待) 19 | - [终端控制](#终端控制) 20 | - [光标控制](#光标控制) 21 | - [终端尺寸](#终端尺寸) 22 | - [清屏功能](#清屏功能) 23 | - [进度条](#进度条) 24 | - [系统相关API](#系统相关api) 25 | - [系统时间](#系统时间) 26 | - [系统命令](#系统命令) 27 | - [系统检测](#系统检测) 28 | - [跨平台兼容性](#跨平台兼容性) 29 | - [按键处理](#按键处理) 30 | - [使用示例](#使用示例) 31 | 32 | ## 基本概述 33 | 34 | TC.hpp 是一个跨平台的终端控制库,提供了丰富的终端操作功能,包括颜色输出、字体样式、光标控制、延时等。该库采用纯头文件设计,无需额外依赖,只需包含 `tc.hpp` 即可使用所有功能。 35 | 36 | 主要特点: 37 | - 跨平台支持(Windows、Linux、macOS) 38 | - 纯头文件,零依赖 39 | - 现代 C++17 设计 40 | - 丰富的终端控制功能 41 | - 简洁易用的 API 42 | - 完整的按键处理支持(包括特殊按键如方向键、功能键等) 43 | 44 | ## 颜色与样式 45 | 46 | ### 前景色 47 | 48 | TC.hpp 提供了一系列前景色宏,可直接在代码中使用: 49 | 50 | | 宏名 | 颜色 | ANSI代码 | 51 | |------|------|----------| 52 | | `TCOLOR_BLACK` | 黑色 | `\033[30m` | 53 | | `TCOLOR_RED` | 红色 | `\033[31m` | 54 | | `TCOLOR_GREEN` | 绿色 | `\033[32m` | 55 | | `TCOLOR_YELLOW` | 黄色 | `\033[33m` | 56 | | `TCOLOR_BLUE` | 蓝色 | `\033[34m` | 57 | | `TCOLOR_MAGENTA` | 洋红 | `\033[35m` | 58 | | `TCOLOR_CYAN` | 青色 | `\033[36m` | 59 | | `TCOLOR_WHITE` | 白色 | `\033[37m` | 60 | | `TCOLOR_DEFAULT` | 默认 | `\033[39m` | 61 | | `TCOLOR_RESET` | 重置 | `\033[0m` | 62 | 63 | 使用示例: 64 | ```cpp 65 | tc::println(TCOLOR_RED, "这是红色文本", TCOLOR_RESET); 66 | ``` 67 | 68 | ### 背景色 69 | 70 | 背景色宏可以设置文本的背景颜色: 71 | 72 | | 宏名 | 颜色 | ANSI代码 | 73 | |------|------|----------| 74 | | `BCOLOR_BLACK` | 黑色 | `\033[40m` | 75 | | `BCOLOR_RED` | 红色 | `\033[41m` | 76 | | `BCOLOR_GREEN` | 绿色 | `\033[42m` | 77 | | `BCOLOR_YELLOW` | 黄色 | `\033[43m` | 78 | | `BCOLOR_BLUE` | 蓝色 | `\033[44m` | 79 | | `BCOLOR_MAGENTA` | 洋红 | `\033[45m` | 80 | | `BCOLOR_CYAN` | 青色 | `\033[46m` | 81 | | `BCOLOR_WHITE` | 白色 | `\033[47m` | 82 | | `BCOLOR_DEFAULT` | 默认 | `\033[49m` | 83 | 84 | 使用示例: 85 | ```cpp 86 | tc::println(TCOLOR_BLACK, BCOLOR_YELLOW, "黑字黄底", TCOLOR_RESET); 87 | ``` 88 | 89 | ### 字体样式 90 | 91 | TC.hpp 支持多种字体样式: 92 | 93 | | 宏名 | 效果 | ANSI代码 | 兼容性 | 94 | |------|------|----------|--------| 95 | | `TFONT_BOLD` | 粗体/加粗 | `\033[1m` | Windows完全支持,其他终端大多支持 | 96 | | `TFONT_FAINT` | 微弱/淡色 | `\033[2m` | Windows完全支持,其他终端部分支持 | 97 | | `TFONT_ITALIC` | 斜体 | `\033[3m` | Windows完全支持,其他终端部分支持 | 98 | | `TFONT_UNDERLINE` | 下划线 | `\033[4m` | Windows完全支持,其他终端大多支持 | 99 | | `TFONT_BLINK_SLOW` | 慢速闪烁 | `\033[5m` | Windows完全支持,其他终端部分支持 | 100 | | `TFONT_BLINK_FAST` | 快速闪烁 | `\033[6m` | Windows完全支持,其他终端很少支持 | 101 | | `TFONT_REVERSE` | 反色 | `\033[7m` | Windows完全支持,其他终端大多支持 | 102 | | `TFONT_CONCEAL` | 隐藏 | `\033[8m` | Windows完全支持,其他终端很少支持 | 103 | | `TFONT_CROSSED` | 删除线 | `\033[9m` | Windows完全支持,其他终端部分支持 | 104 | | `TFONT_RESET` | 全部重置 | `\033[0m` | Windows完全支持,其他终端大多支持 | 105 | 106 | 使用示例: 107 | ```cpp 108 | tc::println(TFONT_BOLD, "粗体文本", TFONT_RESET); 109 | tc::println(TFONT_UNDERLINE, "下划线文本", TFONT_RESET); 110 | ``` 111 | 112 | ### RGB颜色 113 | 114 | TC.hpp 支持 RGB 颜色设置: 115 | 116 | ```cpp 117 | tc::println(TCOLOR_RGB(255, 0, 0), "自定义红色", TCOLOR_RESET); 118 | ``` 119 | 120 | ## 输出函数 121 | 122 | ### 标准输出 123 | 124 | TC.hpp 提供了类似 Python 的 print/println 函数: 125 | 126 | ```cpp 127 | // 多参数打印 128 | tc::print("Hello", " ", "World"); // 输出: Hello World 129 | tc::println("Hello", " ", "World"); // 输出: Hello World 并换行 130 | 131 | // 带颜色的打印 132 | tc::println(TCOLOR_GREEN, "绿色文本", TCOLOR_RESET); 133 | ``` 134 | 135 | ### 链式输出 136 | 137 | TC.hpp 提供了流式输出接口: 138 | 139 | ```cpp 140 | // 流式输出 141 | tc::tout << TCOLOR_BLUE << "蓝色文本" << TCOLOR_RESET << std::endl; 142 | 143 | // 链式 Printer API 144 | tc::printer() 145 | .moveCursor(10, 5) 146 | .print("在位置(10,5)打印") 147 | .moveCursor(10, 6) 148 | .println("下一行"); 149 | ``` 150 | 151 | ## 延时与等待 152 | 153 | ### 延时函数 154 | 155 | TC.hpp 提供了多种延时函数: 156 | 157 | ```cpp 158 | // 等待指定秒数(支持小数) 159 | tc::wait(1.5); // 等待1.5秒 160 | 161 | // 等待指定毫秒 162 | tc::tsleep(1000).execute(); // 等待1000毫秒 163 | 164 | // 流式延时 165 | tc::tout << "等待前" << tc::tsleep(500) << "等待后" << std::endl; 166 | 167 | // 延时流 168 | tc::tsleep_stream << 1000; // 等待1000毫秒 169 | ``` 170 | 171 | ### 按键等待 172 | 173 | TC.hpp 提供了等待按键的功能: 174 | 175 | ```cpp 176 | // 等待任意按键 177 | tc::waitKey(); 178 | 179 | // 等待特定按键 180 | tc::waitKey('A'); // 等待按下A键 181 | tc::waitKey(KEY_ESC); // 等待按下ESC键 182 | ``` 183 | 184 | 常用特殊按键宏: 185 | 186 | | 宏名 | 按键 | 187 | |------|------| 188 | | `KEY_ESC` | ESC键 | 189 | | `KEY_SPACE` | 空格键 | 190 | | `KEY_ENTER` | 回车键 | 191 | | `KEY_TAB` | Tab键 | 192 | | `KEY_BACKSPACE` | 退格键 | 193 | | `KEY_UP` | 上方向键 | 194 | | `KEY_DOWN` | 下方向键 | 195 | | `KEY_LEFT` | 左方向键 | 196 | | `KEY_RIGHT` | 右方向键 | 197 | | `KEY_F1` ~ `KEY_F12` | F1-F12功能键 | 198 | | `KEY_INSERT` | Insert键 | 199 | | `KEY_DELETE` | Delete键 | 200 | | `KEY_HOME` | Home键 | 201 | | `KEY_END` | End键 | 202 | | `KEY_PAGEUP` | PageUp键 | 203 | | `KEY_PAGEDOWN` | PageDown键 | 204 | 205 | ## 终端控制 206 | 207 | ### 光标控制 208 | 209 | TC.hpp 提供了光标控制功能: 210 | 211 | ```cpp 212 | // 移动光标到指定位置 213 | tc::printer().moveCursor(10, 5); // 移动到第5行,第10列 214 | 215 | // 隐藏/显示光标 216 | tc::printer().hideCursor(); 217 | tc::printer().showCursor(); 218 | 219 | // 相对移动光标 220 | tc::printer().moveCursor(tc::Printer::Direction::Up, 2); // 上移2行 221 | tc::printer().moveCursor(tc::Printer::Direction::Right, 5); // 右移5列 222 | ``` 223 | 224 | ### 终端尺寸 225 | 226 | 获取终端窗口大小: 227 | 228 | ```cpp 229 | auto size = tc::printer().getSize(); 230 | tc::println("终端大小: ", size.first, "x", size.second); // 宽x高 231 | ``` 232 | 233 | ### 清屏功能 234 | 235 | 清除终端内容: 236 | 237 | ```cpp 238 | tc::printer().clear(); // 清屏并将光标移到左上角 239 | ``` 240 | 241 | ## 进度条 242 | 243 | TC.hpp 提供了简单易用的进度条功能: 244 | 245 | ```cpp 246 | // 创建进度条(宽度30,填充字符"█",未填充字符"░",绿色) 247 | tc::ProgressBar bar(30, "█", "░", TCOLOR_GREEN); 248 | 249 | // 显示进度(0.0-1.0之间) 250 | for (int i = 0; i <= 100; ++i) { 251 | bar.show(i / 100.0, "处理中..."); 252 | tc::wait(0.02); // 模拟处理时间 253 | } 254 | 255 | // 完成进度条 256 | bar.finish("完成!"); 257 | ``` 258 | 259 | ## 系统相关API 260 | 261 | ### 系统时间 262 | 263 | TC.hpp 提供了获取系统时间的功能: 264 | 265 | ```cpp 266 | // 获取当前年份 267 | int year = tc::getSystemTime(SYS_YEAR); 268 | 269 | // 获取当前月份 270 | int month = tc::getSystemTime(SYS_MONTH); 271 | 272 | // 获取Unix时间戳 273 | int timestamp = tc::getSystemTime(); // 默认返回时间戳 274 | ``` 275 | 276 | 时间宏定义: 277 | 278 | | 宏名 | 返回值 | 279 | |------|--------| 280 | | `SYS_YEAR` | 年份 | 281 | | `SYS_MONTH` | 月份(1-12) | 282 | | `SYS_DAY` | 日期(1-31) | 283 | | `SYS_HOUR` | 小时(0-23) | 284 | | `SYS_MINUTE` | 分钟(0-59) | 285 | | `SYS_SECOND` | 秒(0-59) | 286 | | `SYS_TIMESTAMP` | Unix时间戳 | 287 | 288 | ### 系统命令 289 | 290 | 执行系统命令: 291 | 292 | ```cpp 293 | // 执行系统命令 294 | tc::systemConsole("echo Hello World"); 295 | ``` 296 | 297 | ### 系统检测 298 | 299 | TC.hpp 提供了检测当前操作系统的功能: 300 | 301 | ```cpp 302 | // 获取当前操作系统类型 303 | int os = tc::systemCheck(); 304 | 305 | // 根据返回值判断系统类型 306 | switch (os) { 307 | case OS_WINDOWSNT11: 308 | tc::println("Windows 11"); 309 | break; 310 | case OS_LINUX: 311 | tc::println("Linux"); 312 | break; 313 | // 其他系统类型... 314 | } 315 | ``` 316 | 317 | 主要系统类型宏: 318 | 319 | | 宏名 | 系统类型 | 320 | |------|----------| 321 | | `OS_WINDOWSNT11` | Windows 11 | 322 | | `OS_WINDOWSNT10` | Windows 10 | 323 | | `OS_WINDOWSNT6` | Windows Vista/7/8/8.1 | 324 | | `OS_LINUX` | Linux | 325 | | `OS_ANDROID` | Android | 326 | | `OS_MACOS` | macOS | 327 | | `OS_IOS` | iOS | 328 | | `OS_BSD` | BSD | 329 | | `OS_UNIX` | Unix-like | 330 | 331 | ## 跨平台兼容性 332 | 333 | TC.hpp 在不同平台上的实现方式: 334 | 335 | - **Windows**: 使用 Windows Console API(Win32 API)实现终端控制功能,不使用ANSI转义序列 336 | - **Linux/macOS**: 使用 ANSI 转义序列和 POSIX API 337 | 338 | 库会自动检测平台并使用适当的实现,无需用户手动配置。所有颜色、字体样式和终端控制功能在Windows平台上都能完全支持,因为它们直接使用了原生的Win32 API,而不依赖于终端对ANSI转义序列的支持。 339 | 340 | ## 按键处理 341 | 342 | TC.hpp 提供了完整的按键处理支持,包括特殊按键如方向键、功能键等。在Windows平台上,库使用了 `_getch()` 函数来捕获按键,并对扩展键(如方向键)进行了特殊处理,确保它们能够正确识别。 343 | 344 | ```cpp 345 | // 检测按键 346 | tc::println("按方向键测试:"); 347 | tc::println("按上方向键..."); 348 | tc::waitKey(KEY_UP); 349 | tc::println("检测到上方向键"); 350 | 351 | // 在游戏循环中使用按键检测 352 | while (!gameOver) { 353 | if (_kbhit()) { // 检查是否有按键按下 354 | int key = _getch(); 355 | // 处理特殊键(方向键等) 356 | if (key == 0 || key == 224) { 357 | key = _getch(); 358 | switch (key) { 359 | case 72: handleUpKey(); break; // 上方向键 360 | case 80: handleDownKey(); break; // 下方向键 361 | case 75: handleLeftKey(); break; // 左方向键 362 | case 77: handleRightKey(); break; // 右方向键 363 | } 364 | } else { 365 | // 处理普通键 366 | handleNormalKey(key); 367 | } 368 | } 369 | // 游戏逻辑更新... 370 | } 371 | ``` 372 | 373 | ## 使用示例 374 | 375 | 完整示例程序: 376 | 377 | ```cpp 378 | #include "tc.hpp" 379 | 380 | int main() { 381 | // 清屏 382 | tc::printer().clear(); 383 | 384 | // 标题 385 | tc::println(TCOLOR_CYAN, TFONT_BOLD, "TC.hpp 功能演示", TCOLOR_RESET); 386 | tc::println(); 387 | 388 | // 颜色演示 389 | tc::println("=== 颜色演示 ==="); 390 | tc::println(TCOLOR_RED, "红色文本", TCOLOR_RESET); 391 | tc::println(TCOLOR_GREEN, "绿色文本", TCOLOR_RESET); 392 | tc::println(TCOLOR_BLUE, "蓝色文本", TCOLOR_RESET); 393 | tc::println(TCOLOR_YELLOW, BCOLOR_BLUE, "黄字蓝底", TCOLOR_RESET); 394 | tc::println(TCOLOR_RGB(255, 128, 0), "自定义橙色", TCOLOR_RESET); 395 | tc::println(); 396 | 397 | // 字体样式演示 398 | tc::println("=== 字体样式演示 ==="); 399 | tc::println(TFONT_BOLD, "粗体文本", TCOLOR_RESET); 400 | tc::println(TFONT_UNDERLINE, "下划线文本", TCOLOR_RESET); 401 | tc::println(TFONT_ITALIC, "斜体文本", TCOLOR_RESET); 402 | tc::println(TFONT_CROSSED, "删除线文本", TCOLOR_RESET); 403 | tc::println(); 404 | 405 | // 进度条演示 406 | tc::println("=== 进度条演示 ==="); 407 | tc::ProgressBar bar(30, "█", "░", TCOLOR_GREEN); 408 | for (int i = 0; i <= 100; i += 10) { 409 | bar.show(i / 100.0, "处理中..."); 410 | tc::wait(0.2); 411 | } 412 | bar.finish("完成!"); 413 | tc::println(); 414 | 415 | // 按键演示 416 | tc::println("=== 按键演示 ==="); 417 | tc::println("按上方向键继续..."); 418 | tc::waitKey(KEY_UP); 419 | tc::println("检测到上方向键!"); 420 | tc::println(); 421 | 422 | // 系统信息演示 423 | tc::println("=== 系统信息 ==="); 424 | int year = tc::getSystemTime(SYS_YEAR); 425 | int month = tc::getSystemTime(SYS_MONTH); 426 | int day = tc::getSystemTime(SYS_DAY); 427 | tc::println("当前日期: ", year, "-", month, "-", day); 428 | 429 | int os = tc::systemCheck(); 430 | tc::print("当前系统: "); 431 | switch (os) { 432 | case OS_WINDOWSNT11: tc::println("Windows 11"); break; 433 | case OS_WINDOWSNT10: tc::println("Windows 10"); break; 434 | case OS_LINUX: tc::println("Linux"); break; 435 | case OS_MACOS: tc::println("macOS"); break; 436 | default: tc::println("其他系统"); 437 | } 438 | 439 | tc::println("\n按任意键退出..."); 440 | tc::waitKey(); 441 | 442 | return 0; 443 | } 444 | ``` 445 | 446 | --- 447 | 448 | 本文档提供了 TC.hpp 库的主要功能概述。更多详细信息和高级用法,请参考源代码中的注释和示例。 -------------------------------------------------------------------------------- /include/tc_system_utils.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tc_system_utils.hpp - TC库系统工具模块 3 | * TC System Utilities Module 4 | * 5 | * 这个文件包含了TC库中的系统工具功能,包括: 6 | * - 系统时间获取功能 7 | * - 系统命令执行功能 8 | * - 跨平台系统操作支持 9 | * - 时间相关常量定义 10 | * - 按键状态检测功能 11 | * - 按键码常量定义 12 | * 13 | * This file contains system utility functionality in the TC library, including: 14 | * - System time retrieval functionality 15 | * - System command execution functionality 16 | * - Cross-platform system operation support 17 | * - Time-related constant definitions 18 | * - Key state detection functionality 19 | * - Key code constant definitions 20 | * 21 | * 版本 Version: 1.1.1 22 | * 作者 Author: 537 Studio 23 | * 许可 License: MIT 24 | */ 25 | 26 | #ifndef TC_SYSTEM_UTILS_HPP 27 | #define TC_SYSTEM_UTILS_HPP 28 | 29 | // 标准库包含 | Standard library includes 30 | #include // 时间相关函数 | Time-related functions 31 | #include // 系统函数,如system() | System functions like system() 32 | #include // 字符串类 | String class 33 | 34 | // 平台特定包含 | Platform-specific includes 35 | #ifdef _WIN32 36 | #include // Windows API 37 | #include // Windows控制台输入输出函数 | Windows console I/O functions 38 | #else 39 | #include // 终端IO设置 | Terminal I/O settings 40 | #include // POSIX API | POSIX API 41 | #include // 文件控制定义 | File control definitions 42 | #include // I/O控制 | I/O control 43 | #endif 44 | 45 | /** 46 | * 按键常量定义,用于isKeyPressed和waitKey函数 47 | * Key constants for isKeyPressed and waitKey functions 48 | * 49 | * 这些常量定义了常用的特殊按键的键码值,可以用于isKeyPressed和waitKey函数 50 | * 来检测或等待特定的按键输入。这些值在不同平台上可能有所不同。 51 | * 52 | * These constants define key code values for common special keys, which can be used 53 | * with the isKeyPressed and waitKey functions to detect or wait for specific key input. 54 | * These values may vary across different platforms. 55 | */ 56 | // 基本控制键 | Basic control keys 57 | #define KEY_ESC 27 // Escape键 | Escape key 58 | #define KEY_SPACE 32 // 空格键 | Space key 59 | #define KEY_TAB 9 // Tab键 | Tab key 60 | #ifdef _WIN32 61 | #define KEY_ENTER 13 // 回车键 | Enter key (Windows uses '\r') 62 | #define KEY_BACKSPACE 8 // 退格键 | Backspace key (Windows uses Ctrl+H) 63 | #else 64 | #define KEY_ENTER 10 // 回车键 | Enter key (Unix/Linux uses '\n') 65 | #define KEY_BACKSPACE 127 // 退格键 | Backspace key (Unix/Linux uses DEL) 66 | #endif 67 | 68 | // 编辑键 | Editing keys 69 | #ifdef _WIN32 70 | #define KEY_INSERT 0x52 // Insert键 | Insert key 71 | #define KEY_DELETE 0x53 // Delete键 | Delete key 72 | #define KEY_HOME 0x47 // Home键 | Home key 73 | #define KEY_END 0x4F // End键 | End key 74 | #define KEY_PAGEUP 0x49 // Page Up键 | Page Up key 75 | #define KEY_PAGEDOWN 0x51 // Page Down键 | Page Down key 76 | #else 77 | // Unix/Linux 下特殊键需用转义序列解析,以下宏用于 ESC 序列检测 78 | #define KEY_INSERT '2' // ESC [ 2~ 79 | #define KEY_DELETE '3' // ESC [ 3~ 80 | #define KEY_HOME 'H' // ESC [ H 81 | #define KEY_END 'F' // ESC [ F 82 | #define KEY_PAGEUP '5' // ESC [ 5~ 83 | #define KEY_PAGEDOWN '6' // ESC [ 6~ 84 | #endif 85 | 86 | // 方向键 | Arrow keys 87 | #ifdef _WIN32 88 | #define KEY_UP 72 // 上箭头键 | Up arrow key 89 | #define KEY_DOWN 80 // 下箭头键 | Down arrow key 90 | #define KEY_LEFT 75 // 左箭头键 | Left arrow key 91 | #define KEY_RIGHT 77 // 右箭头键 | Right arrow key 92 | #else 93 | #define KEY_UP 'A' 94 | #define KEY_DOWN 'B' 95 | #define KEY_RIGHT 'C' 96 | #define KEY_LEFT 'D' 97 | #endif 98 | 99 | // 功能键 | Function keys 100 | #ifdef _WIN32 101 | #define KEY_F1 0x3B // F1功能键 | F1 function key 102 | #define KEY_F2 0x3C // F2功能键 | F2 function key 103 | #define KEY_F3 0x3D // F3功能键 | F3 function key 104 | #define KEY_F4 0x3E // F4功能键 | F4 function key 105 | #define KEY_F5 0x3F // F5功能键 | F5 function key 106 | #define KEY_F6 0x40 // F6功能键 | F6 function key 107 | #define KEY_F7 0x41 // F7功能键 | F7 function key 108 | #define KEY_F8 0x42 // F8功能键 | F8 function key 109 | #define KEY_F9 0x43 // F9功能键 | F9 function key 110 | #define KEY_F10 0x44 // F10功能键 | F10 function key 111 | #define KEY_F11 0x85 // F11功能键 | F11 function key 112 | #define KEY_F12 0x86 // F12功能键 | F12 function key 113 | #else 114 | #define KEY_F1 'P' // ESC O P 115 | #define KEY_F2 'Q' // ESC O Q 116 | #define KEY_F3 'R' // ESC O R 117 | #define KEY_F4 'S' // ESC O S 118 | #define KEY_F5 15 // ESC [ 1 5 ~ 119 | #define KEY_F6 17 // ESC [ 1 7 ~ 120 | #define KEY_F7 18 // ESC [ 1 8 ~ 121 | #define KEY_F8 19 // ESC [ 1 9 ~ 122 | #define KEY_F9 20 // ESC [ 2 0 ~ 123 | #define KEY_F10 21 // ESC [ 2 1 ~ 124 | #define KEY_F11 23 // ESC [ 2 3 ~ 125 | #define KEY_F12 24 // ESC [ 2 4 ~ 126 | #endif 127 | 128 | /** 129 | * 系统时间常量,用于getSystemTime函数 130 | * System time constants for getSystemTime function 131 | * 132 | * 这些常量定义了getSystemTime函数可以返回的不同时间组件。 133 | * 默认情况下返回Unix时间戳(自1970年1月1日起的秒数)。 134 | * 135 | * These constants define different time components that the getSystemTime function can return. 136 | * By default, it returns Unix timestamp (seconds since January 1, 1970). 137 | */ 138 | #define SYS_YEAR 1 // 年份 | Year 139 | #define SYS_MONTH 2 // 月份(1-12) | Month (1-12) 140 | #define SYS_DAY 3 // 日期(1-31) | Day (1-31) 141 | #define SYS_HOUR 4 // 小时(0-23) | Hour (0-23) 142 | #define SYS_MINUTE 5 // 分钟(0-59) | Minute (0-59) 143 | #define SYS_SECOND 6 // 秒钟(0-59) | Second (0-59) 144 | #define SYS_TIMESTAMP 0 // Unix时间戳 | Unix timestamp 145 | 146 | namespace tc { 147 | 148 | /** 149 | * 获取系统时间 150 | * Get system time 151 | * 152 | * 这个函数返回当前系统时间的各个组成部分,如年、月、日等, 153 | * 或者返回Unix时间戳(自1970年1月1日起的秒数)。 154 | * 在Windows平台上使用线程安全的localtime_s函数。 155 | * 156 | * This function returns various components of the current system time, 157 | * such as year, month, day, etc., or returns the Unix timestamp 158 | * (seconds since January 1, 1970). 159 | * On Windows platform, uses thread-safe localtime_s function. 160 | * 161 | * @param type 时间类型常量,默认为时间戳 | Time type constant, defaults to timestamp 162 | * 可选值:SYS_YEAR, SYS_MONTH, SYS_DAY, SYS_HOUR, SYS_MINUTE, SYS_SECOND, SYS_TIMESTAMP 163 | * Possible values: SYS_YEAR, SYS_MONTH, SYS_DAY, SYS_HOUR, SYS_MINUTE, SYS_SECOND, SYS_TIMESTAMP 164 | * @return 请求的时间值 | Requested time value 165 | */ 166 | inline int getSystemTime(int type = SYS_TIMESTAMP) { 167 | // 获取当前时间的时间戳 | Get current time timestamp 168 | std::time_t t = std::time(nullptr); 169 | std::tm* tm_ptr; 170 | 171 | #ifdef _WIN32 172 | // Windows平台使用线程安全版本 | Windows platform uses thread-safe version 173 | std::tm tm_buf; 174 | localtime_s(&tm_buf, &t); 175 | tm_ptr = &tm_buf; 176 | #else 177 | // 非Windows平台使用标准版本 | Non-Windows platform uses standard version 178 | // 注意:在某些系统上,localtime可能不是线程安全的 | Note: On some systems, localtime may not be thread-safe 179 | tm_ptr = std::localtime(&t); 180 | #endif 181 | 182 | // 根据请求的类型返回相应的时间值 | Return appropriate time value based on requested type 183 | switch(type) { 184 | case SYS_YEAR: return tm_ptr->tm_year + 1900; // 年份(tm_year是从1900年开始的) | Year (tm_year is years since 1900) 185 | case SYS_MONTH: return tm_ptr->tm_mon + 1; // 月份(tm_mon范围是0-11) | Month (tm_mon range is 0-11) 186 | case SYS_DAY: return tm_ptr->tm_mday; // 日期 | Day of month 187 | case SYS_HOUR: return tm_ptr->tm_hour; // 小时 | Hour 188 | case SYS_MINUTE: return tm_ptr->tm_min; // 分钟 | Minute 189 | case SYS_SECOND: return tm_ptr->tm_sec; // 秒钟 | Second 190 | default: return static_cast(t); // 默认返回时间戳 | Default returns timestamp 191 | } 192 | } 193 | 194 | /** 195 | * 执行系统命令(C字符串版本) 196 | * Execute system command (C string version) 197 | * 198 | * 这个函数使用系统的命令处理器执行指定的命令。 199 | * 命令在当前系统的默认shell中执行。 200 | * 201 | * This function executes the specified command using the system's command processor. 202 | * The command is executed in the current system's default shell. 203 | * 204 | * @param cmd 要执行的命令 | Command to execute 205 | * @return 命令的退出状态 | Exit status of the command 206 | */ 207 | inline int systemConsole(const char* cmd) { 208 | return std::system(cmd); 209 | } 210 | 211 | /** 212 | * 执行系统命令(C++字符串版本) 213 | * Execute system command (C++ string version) 214 | * 215 | * 这个函数是systemConsole的重载版本,接受C++字符串。 216 | * 内部将std::string转换为C字符串后调用系统函数。 217 | * 218 | * This function is an overloaded version of systemConsole that accepts C++ strings. 219 | * Internally converts std::string to C string before calling system function. 220 | * 221 | * @param cmd 要执行的命令 | Command to execute 222 | * @return 命令的退出状态 | Exit status of the command 223 | */ 224 | inline int systemConsole(const std::string& cmd) { 225 | return std::system(cmd.c_str()); 226 | } 227 | 228 | #ifdef _WIN32 229 | /** 230 | * 执行系统命令(宽字符版本) 231 | * Execute system command (wide character version) 232 | * 233 | * 这个函数是systemConsole的宽字符版本,用于支持Unicode命令。 234 | * 仅在Windows平台上可用,直接使用_wsystem函数。 235 | * 236 | * This function is a wide character version of systemConsole for Unicode command support. 237 | * Only available on Windows platform, directly uses _wsystem function. 238 | * 239 | * @param cmd 要执行的宽字符命令 | Wide character command to execute 240 | * @return 命令的退出状态 | Exit status of the command 241 | */ 242 | inline int systemConsoleW(const wchar_t* cmd) { 243 | return _wsystem(cmd); 244 | } 245 | #endif 246 | 247 | /** 248 | * 检查指定按键是否被按下 249 | * Check if a specific key is pressed 250 | * 251 | * 这个函数检查指定的按键是否当前被按下。 252 | * 可以使用字符或按键码常量作为参数。 253 | * 254 | * This function checks if a specific key is currently pressed. 255 | * Can use either a character or key code constant as parameter. 256 | * 257 | * @param key 要检查的按键(字符或按键码常量) | Key to check (character or key code constant) 258 | * @return 如果按键被按下返回true,否则返回false | Returns true if key is pressed, false otherwise 259 | */ 260 | #ifdef _WIN32 261 | inline bool isKeyPressed(int key) { 262 | // Windows平台使用GetAsyncKeyState API 263 | // Windows platform uses GetAsyncKeyState API 264 | 265 | // 对于一些特殊键,需要进行转换 266 | // For some special keys, conversion is needed 267 | switch(key) { 268 | case KEY_UP: return (GetAsyncKeyState(VK_UP) & 0x8000) != 0; 269 | case KEY_DOWN: return (GetAsyncKeyState(VK_DOWN) & 0x8000) != 0; 270 | case KEY_LEFT: return (GetAsyncKeyState(VK_LEFT) & 0x8000) != 0; 271 | case KEY_RIGHT: return (GetAsyncKeyState(VK_RIGHT) & 0x8000) != 0; 272 | case KEY_ENTER: return (GetAsyncKeyState(VK_RETURN) & 0x8000) != 0; 273 | case KEY_ESC: return (GetAsyncKeyState(VK_ESCAPE) & 0x8000) != 0; 274 | case KEY_SPACE: return (GetAsyncKeyState(VK_SPACE) & 0x8000) != 0; 275 | case KEY_TAB: return (GetAsyncKeyState(VK_TAB) & 0x8000) != 0; 276 | case KEY_BACKSPACE: return (GetAsyncKeyState(VK_BACK) & 0x8000) != 0; 277 | default: return (GetAsyncKeyState(key) & 0x8000) != 0; 278 | } 279 | } 280 | 281 | // 字符版本重载 282 | // Character version overload 283 | inline bool isKeyPressed(char key) { 284 | return isKeyPressed(static_cast(key)); 285 | } 286 | #else 287 | // 非Windows平台实现 288 | // Non-Windows platform implementation 289 | inline bool isKeyPressed(int key) { 290 | struct termios oldt, newt; 291 | int ch; 292 | int oldf; 293 | tcgetattr(STDIN_FILENO, &oldt); 294 | newt = oldt; 295 | newt.c_lflag &= ~(ICANON | ECHO); 296 | tcsetattr(STDIN_FILENO, TCSANOW, &newt); 297 | oldf = fcntl(STDIN_FILENO, F_GETFL, 0); 298 | fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); 299 | ch = getchar(); 300 | tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 301 | fcntl(STDIN_FILENO, F_SETFL, oldf); 302 | if (ch == 27) { // ESC 序列 303 | ch = getchar(); 304 | if (ch == '[') { 305 | ch = getchar(); 306 | // 方向键 307 | if (key == 'A' && ch == 'A') return true; 308 | if (key == 'B' && ch == 'B') return true; 309 | if (key == 'C' && ch == 'C') return true; 310 | if (key == 'D' && ch == 'D') return true; 311 | // Insert/Delete/Home/End/PageUp/PageDown 312 | if (key == KEY_INSERT && ch == '2') { getchar(); return true; } 313 | if (key == KEY_DELETE && ch == '3') { getchar(); return true; } 314 | if (key == KEY_HOME && ch == '1') { getchar(); return true; } 315 | if (key == KEY_END && ch == '4') { getchar(); return true; } 316 | if (key == KEY_PAGEUP && ch == '5') { getchar(); return true; } 317 | if (key == KEY_PAGEDOWN && ch == '6') { getchar(); return true; } 318 | } 319 | } else if (ch != EOF) { 320 | ungetc(ch, stdin); 321 | return (ch == key); 322 | } 323 | return false; 324 | } 325 | 326 | // 字符版本重载 327 | // Character version overload 328 | inline bool isKeyPressed(char key) { 329 | return isKeyPressed(static_cast(key)); 330 | } 331 | #endif 332 | 333 | } // namespace tc 334 | 335 | #endif // TC_SYSTEM_UTILS_HPP 336 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TC.hpp - ✨ 跨平台终端控制头文件库 2 | 3 | [![C++17](https://img.shields.io/badge/C%2B%2B-17%2B-blue.svg)](https://en.cppreference.com/w/cpp/compiler_support) 4 | ![平台](https://img.shields.io/badge/平台-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg) 5 | ![Header-Only](https://img.shields.io/badge/Header--Only-Yes-green.svg) 6 | [![MIT License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) 7 | 8 | > 🚀 一个现代化的 C++17 终端控制库,旨在用最简单的语法解决开发过程中会遇到的各种问题。目前功能包括终端彩色输出、延时、进度条、基础控制、系统信息检测、获取时间等,跨平台、零依赖、纯头文件! 9 | 10 | --- 11 | 12 | ## ✨ 主要特性 13 | 14 | - 🖥️ 跨平台:Windows/类Unix终端自动适配 15 | - 🎨 丰富色彩:支持前景色、背景色、RGB、字体样式 16 | - 💡 现代C++17,纯头文件,零依赖 17 | - ⏱️ 延时与打字机特效 18 | - 📊 进度条、链式API、终端尺寸/光标控制 19 | - 🧩 代码风格简洁,易于集成 20 | 21 | --- 22 | 23 | ## 🚀 快速上手 24 | 25 | ### 1. 引入头文件 26 | 27 | ```cpp 28 | #include "tc.hpp" 29 | ``` 30 | 31 | ### 2. 主要用法示例 32 | 33 | ```cpp 34 | #include "tc.hpp" 35 | 36 | int main() { 37 | // 🌈 颜色与样式 38 | tc::tout << TCOLOR_GREEN << "Hello world!" << TCOLOR_RESET << std::endl; 39 | tc::tout << TFONT_BOLD << "粗体文本" << TFONT_RESET << std::endl; 40 | tc::tout << TCOLOR_RGB(255,0,0) << "RGB红" << TCOLOR_RESET << std::endl; 41 | std::cout << tc::red("红色文本") << std::endl; 42 | 43 | // ⏱️ 延时输出 44 | tc::tout << "Wait..." << std::endl; 45 | tc::tsleep(1000); 46 | tc::tout << "Done!" << std::endl; 47 | 48 | // 🖨️ Python风格打印 49 | tc::print("Hello ", "world!\n"); 50 | tc::println("年龄: ", 25, ", 分数: ", 95.5); 51 | tc::println(TCOLOR_RED, "红色文本"); 52 | tc::println(TCOLOR_GREEN, BCOLOR_YELLOW, "绿色文字,黄色背景"); 53 | tc::println(TCOLOR_BLUE, BCOLOR_WHITE, TFONT_BOLD, "蓝色粗体,白色背景"); 54 | 55 | // 🖋️ Printer链式API 56 | tc::printer() 57 | .clear() // 清屏 58 | .moveCursor(10,5) 59 | .print("移动光标到(10,5)") 60 | .hideCursor() // 隐藏光标 61 | .moveCursor(tc::Printer::Direction::Down, 2) // 相对移动(向下2行) 62 | .println("在(10,7)") 63 | .println() // 换行 64 | .showCursor(); // 显示光标 65 | 66 | // 📏 终端尺寸 67 | auto size = tc::printer().getSize(); 68 | tc::println("终端大小: ", size.first, "x", size.second); 69 | 70 | // ⏳ 进度条 71 | tc::ProgressBar bar(30, "█", "░", TCOLOR_GREEN); 72 | for (int i = 0; i <= 100; ++i) { 73 | bar.show(i / 100.0, "处理中..."); 74 | tc::wait(0.02); 75 | } 76 | bar.finish(); 77 | 78 | // 🖥️ 执行系统命令 79 | tc::systemConsole("echo TC systemConsole test"); 80 | 81 | // 🕒 获取系统时间 82 | int year = tc::getSystemTime(SYS_YEAR); 83 | int month = tc::getSystemTime(SYS_MONTH); 84 | int day = tc::getSystemTime(SYS_DAY); 85 | int hour = tc::getSystemTime(SYS_HOUR); 86 | int minute = tc::getSystemTime(SYS_MINUTE); 87 | int second = tc::getSystemTime(SYS_SECOND); 88 | int timestamp = tc::getSystemTime(); // 默认Unix时间戳 89 | tc::println("当前时间: ", year, "-", month, "-", day, " ", hour, ":", minute, ":", second, " (Unix: ", timestamp, ")"); 90 | 91 | // 🛡️ 检查系统环境 92 | int os = tc::systemCheck(); 93 | const char* osName = tc::getOSName(os); 94 | std::string osVersionInfo = tc::getOSVersionInfo(); 95 | 96 | tc::println("当前系统: ", osName); 97 | tc::println("系统版本: ", osVersionInfo); 98 | 99 | return 0; 100 | } 101 | ``` 102 | 103 | --- 104 | 105 | ## 🧩 主要API与宏 106 | 107 | ### 🎨 颜色与样式 108 | 109 | #### 全局颜色宏(直接用) 110 | 111 | ```cpp 112 | // 前景色 113 | TCOLOR_RED, TCOLOR_GREEN, TCOLOR_YELLOW, TCOLOR_BLUE, TCOLOR_MAGENTA, TCOLOR_CYAN, TCOLOR_WHITE, TCOLOR_RESET 114 | // 背景色 115 | BCOLOR_RED, BCOLOR_GREEN, BCOLOR_YELLOW, BCOLOR_BLUE, BCOLOR_MAGENTA, BCOLOR_CYAN, BCOLOR_WHITE, BCOLOR_DEFAULT 116 | // 字体样式 117 | TFONT_BOLD, TFONT_FAINT, TFONT_ITALIC, TFONT_UNDERLINE, TFONT_BLINK_SLOW, TFONT_BLINK_FAST, TFONT_REVERSE, TFONT_CONCEAL, TFONT_CROSSED, TFONT_DEFAULT, TFONT_FRAKTUR, TFONT_DOUBLE_UNDERLINE, TFONT_NORMAL, TFONT_NOT_ITALIC, TFONT_NO_UNDERLINE, TFONT_NO_BLINK, TFONT_NO_REVERSE, TFONT_REVEAL, TFONT_NOT_CROSSED, TFONT_THICK, TFONT_RESET 118 | // RGB 119 | TCOLOR_RGB(r, g, b) 120 | ``` 121 | 122 | #### 颜色控制类(ColorController) 123 | 124 | ```cpp 125 | // 设置颜色 126 | tc::ColorController::setColor(tc::ColorController::Color::RED); 127 | std::cout << "红色文本" << std::endl; 128 | 129 | // 设置RGB颜色 130 | tc::ColorController::setRGBColor(255, 128, 0); 131 | std::cout << "橙色文本" << std::endl; 132 | 133 | // 设置粗体 134 | tc::ColorController::setBold(true); 135 | std::cout << "粗体文本" << std::endl; 136 | 137 | // 重置颜色 138 | tc::ColorController::setColor(tc::ColorController::Color::RESET); 139 | ``` 140 | 141 | #### 便捷颜色函数 142 | 143 | > ⚠ 注意:便捷颜色函数本质上是在字符串头尾添加 ANSI 转义序列,最好不要在输出上滥用,并且部分终端不支持 ANSI 转移序列。想要做文本带颜色输出,推荐移步其它方法。 144 | 145 | ```cpp 146 | // 基本颜色函数 147 | std::string coloredText = tc::colorize("彩色文本", tc::ColorController::Color::CYAN); 148 | std::cout << coloredText << std::endl; 149 | 150 | // RGB颜色函数 151 | std::string rgbText = tc::colorizeRGB("RGB颜色文本", 255, 128, 0); 152 | std::cout << rgbText << std::endl; 153 | 154 | // 标准颜色函数 155 | std::cout << tc::red("红色文本") << std::endl; 156 | std::cout << tc::green("绿色文本") << std::endl; 157 | std::cout << tc::blue("蓝色文本") << std::endl; 158 | std::cout << tc::yellow("黄色文本") << std::endl; 159 | std::cout << tc::cyan("青色文本") << std::endl; 160 | std::cout << tc::magenta("洋红色文本") << std::endl; 161 | std::cout << tc::white("白色文本") << std::endl; 162 | 163 | // 亮色函数 164 | std::cout << tc::brightRed("亮红色文本") << std::endl; 165 | std::cout << tc::brightGreen("亮绿色文本") << std::endl; 166 | std::cout << tc::brightBlue("亮蓝色文本") << std::endl; 167 | std::cout << tc::brightYellow("亮黄色文本") << std::endl; 168 | ``` 169 | 170 | ### 字体样式宏(TFONT_XXX) 171 | 172 | | 宏名 | 效果 | 兼容性说明 | 173 | |---------------------------|------------------|------------| 174 | | TFONT_BOLD | 粗体/加粗 | 所有平台完全支持 | 175 | | TFONT_FAINT | 微弱/淡色 | Windows完全支持,其他终端部分支持 | 176 | | TFONT_ITALIC | 斜体 | Windows完全支持,其他终端部分支持 | 177 | | TFONT_UNDERLINE | 下划线 | 所有平台完全支持 | 178 | | TFONT_BLINK_SLOW | 慢速闪烁 | Windows完全支持,其他终端部分支持 | 179 | | TFONT_BLINK_FAST | 快速闪烁 | Windows完全支持,其他终端很少支持 | 180 | | TFONT_REVERSE | 反色 | 所有平台完全支持 | 181 | | TFONT_CONCEAL | 隐藏 | Windows完全支持,其他终端很少支持 | 182 | | TFONT_CROSSED | 删除线 | Windows完全支持,其他终端部分支持 | 183 | | TFONT_DEFAULT | 默认字体 | Windows完全支持,其他终端很少支持 | 184 | | TFONT_FRAKTUR | Fraktur字体 | Windows完全支持,其他终端极少支持 | 185 | | TFONT_DOUBLE_UNDERLINE | 双下划线/粗体关闭| Windows完全支持,其他终端部分支持 | 186 | | TFONT_NORMAL | 粗体/淡色关闭 | 所有平台完全支持 | 187 | | TFONT_NOT_ITALIC | 关闭斜体/Fraktur | Windows完全支持,其他终端部分支持 | 188 | | TFONT_NO_UNDERLINE | 关闭下划线 | 所有平台完全支持 | 189 | | TFONT_NO_BLINK | 关闭闪烁 | Windows完全支持,其他终端很少支持 | 190 | | TFONT_NO_REVERSE | 关闭反色 | 所有平台完全支持 | 191 | | TFONT_REVEAL | 关闭隐藏 | Windows完全支持,其他终端很少支持 | 192 | | TFONT_NOT_CROSSED | 关闭删除线 | Windows完全支持,其他终端部分支持 | 193 | | TFONT_THICK | 粗体(别名) | 同TFONT_BOLD | 194 | | TFONT_RESET | 全部重置 | 所有平台完全支持 | 195 | 196 | > ⚠️ **兼容性说明**: 197 | > 198 | > - TC.hpp 在 Windows 平台上使用 Windows Console API(Win32 API)实现终端控制功能,而不使用 ANSI 转义序列,因此所有字体样式在 Windows 平台上都能完全支持,不受终端对 ANSI 转义序列支持程度的限制。 199 | > - Linux/macOS 下使用 ANSI 转义序列实现,主流终端(如 GNOME Terminal、iTerm2、Konsole、Alacritty 等)大多支持常用样式(粗体、下划线、反色、部分斜体/删除线)。 200 | > - TFONT_FRAKTUR、TFONT_DEFAULT、TFONT_DOUBLE_UNDERLINE 等为扩展/实验性样式,在非 Windows 平台上支持度较低。 201 | 202 | 用法示例:`tc::println(TCOLOR_RED, BCOLOR_YELLOW, TFONT_BOLD, "红字黄底粗体")` 203 | 204 | ### 🖥️ 终端控制 205 | 206 | #### tc::terminal命名空间 207 | 208 | ```cpp 209 | // 清空屏幕 210 | tc::terminal::clear(); 211 | 212 | // 移动光标到指定位置 213 | tc::terminal::moveCursor(10, 5); 214 | std::cout << "这是位置(10,5)" << std::endl; 215 | 216 | // 获取终端大小 217 | auto [width, height] = tc::terminal::getSize(); 218 | std::cout << "终端大小: " << width << "x" << height << std::endl; 219 | ``` 220 | 221 | #### tc::Printer链式类 222 | 223 | ```cpp 224 | // 创建Printer对象并执行一系列操作 225 | tc::printer() 226 | .clear() // 清屏 227 | .hideCursor() // 隐藏光标 228 | .moveCursor(10, 5) // 移动到绝对位置 229 | .println("这是位置(10,5)") // 打印并换行 230 | .moveCursor(tc::Printer::Direction::Down, 2) // 相对移动(向下2行) 231 | .println("向下移动了2行") 232 | .moveCursor(1, 10) // 移动到第10行开头 233 | .print("在第10行: ") // 打印不换行 234 | .print("继续在同一行打印") 235 | .println() // 换行 236 | .showCursor(); // 显示光标 237 | ``` 238 | 239 | ### 🔤 输出与打印 240 | 241 | - `tc::tout`:流式输出(支持颜色/样式/延时) 242 | - `tc::print(...)` / `tc::println(...)`:多参数打印,支持颜色/样式宏 243 | 244 | ### ⏱️ 延时与等待 245 | 246 | - `tc::tsleep(ms)` / `tc::tsleep_stream << ms` 247 | - `tc::wait(seconds)` 248 | - `tc::waitKey()` 249 | 250 | ### 📊 进度条 251 | 252 | - `tc::ProgressBar bar(width, doneChar, todoChar, color)` 253 | - `bar.show(progress, msg)` 254 | - `bar.finish()` 255 | 256 | ### 🖥️ 系统相关API 257 | 258 | - `tc::getSystemTime(int type = SYS_TIMESTAMP)`:获取当前时间(年、月、日、时、分、秒、Unix时间戳) 259 | - `tc::systemConsole(const char* 或 std::string)`:执行系统命令 260 | - `tc::systemConsoleW(const wchar_t*)`:执行系统命令(宽字符版本,仅Windows平台可用,支持Unicode命令) 261 | - `tc::systemCheck()`:检测当前操作系统,返回操作系统代码 262 | - `tc::getOSName(int osCode)`:根据操作系统代码返回操作系统名称 263 | - `tc::getOSVersionInfo()`:获取当前操作系统的详细版本信息 264 | 265 | #### 支持的系统宏 266 | 267 | | 类别 | 宏名 | 说明 | 268 | |------|------|------| 269 | | **Windows系列** | OS_WINDOWS | 通用Windows标识 | 270 | | | OS_WINDOWSNT6 | Windows 7/8/8.1 (NT 6.x) | 271 | | | OS_WINDOWSNT10 | Windows 10 (NT 10.0) | 272 | | | OS_WINDOWSNT11 | Windows 11 (NT 10.0 build 22000+) | 273 | | **Linux发行版** | OS_LINUX | 通用Linux标识 | 274 | | | OS_UBUNTU | Ubuntu Linux | 275 | | | OS_DEBIAN | Debian Linux | 276 | | | OS_FEDORA | Fedora Linux | 277 | | | OS_CENTOS | CentOS Linux | 278 | | | OS_REDHAT | Red Hat Enterprise Linux | 279 | | | OS_SUSE | SUSE/openSUSE Linux | 280 | | | OS_ARCH | Arch Linux | 281 | | | OS_GENTOO | Gentoo Linux | 282 | | | OS_SLACKWARE | Slackware Linux | 283 | | | OS_ANDROID | Android (基于Linux) | 284 | | | OS_KALI | Kali Linux | 285 | | | OS_MINT | Linux Mint | 286 | | | OS_MANJARO | Manjaro Linux | 287 | | | OS_ALPINE | Alpine Linux | 288 | | | OS_RASPBIAN | Raspbian | 289 | | | OS_DEEPIN | Deepin Linux | 290 | | | OS_ELEMENTARY | Elementary OS | 291 | | | OS_ZORIN | Zorin OS | 292 | | | OS_POPOS | Pop!_OS | 293 | | | OS_CHROMEOS | Chrome OS/Chromium OS | 294 | | **Apple操作系统** | OS_MACOS | 通用macOS标识 | 295 | | | OS_MACOS_HIGHSIERRA | macOS 10.13 High Sierra (2017) | 296 | | | OS_MACOS_MOJAVE | macOS 10.14 Mojave (2018) | 297 | | | OS_MACOS_CATALINA | macOS 10.15 Catalina (2019) | 298 | | | OS_MACOS_BIGSUR | macOS 11 Big Sur (2020) | 299 | | | OS_MACOS_MONTEREY | macOS 12 Monterey (2021) | 300 | | | OS_MACOS_VENTURA | macOS 13 Ventura (2022) | 301 | | | OS_MACOS_SONOMA | macOS 14 Sonoma (2023) | 302 | | | OS_MACOS_SEQUOIA | macOS 15 Sequoia (2024) | 303 | | | OS_MACOS_TAHOE | macOS 26 Tahoe (2025) | 304 | | **其他Apple操作系统** | OS_IOS | iOS (iPhone/iPod touch) | 305 | | | OS_IPADOS | iPadOS (iPad) | 306 | | | OS_WATCHOS | watchOS (Apple Watch) | 307 | | | OS_TVOS | tvOS (Apple TV) | 308 | | | OS_VISIONOS | visionOS (Apple Vision Pro) | 309 | | | OS_BRIDGEOS | bridgeOS (Apple T2芯片) | 310 | | | OS_AUDIOOS | audioOS (HomePod) | 311 | | **BSD系列** | OS_BSD | 通用BSD标识 | 312 | | | OS_FREEBSD | FreeBSD | 313 | | **Unix系列** | OS_UNIX | 通用Unix标识 | 314 | | **新兴操作系统** | OS_FUCHSIA | Google Fuchsia | 315 | | | OS_HARMONYOS | Harmony OS | 316 | | **其它操作系统** | OS_REACTOS | ReactOS | 317 | | **未知操作系统** | OS_UNKNOWN | 无法识别的操作系统 | 318 | 319 | #### 用法示例 320 | 321 | ```cpp 322 | // 获取系统信息 323 | int osCode = tc::systemCheck(); 324 | const char* osName = tc::getOSName(osCode); 325 | std::string osVersionInfo = tc::getOSVersionInfo(); 326 | 327 | // 显示系统信息 328 | tc::println("操作系统: ", osName); 329 | tc::println("系统版本: ", osVersionInfo); 330 | 331 | // 根据系统类型执行不同操作 332 | switch (osCode) { 333 | case OS_WINDOWSNT11: 334 | tc::println("Windows 11系统特定操作"); 335 | break; 336 | case OS_UBUNTU: 337 | tc::println("Ubuntu系统特定操作"); 338 | break; 339 | case OS_MACOS: 340 | tc::println("macOS系统特定操作"); 341 | break; 342 | // ... 其他系统 ... 343 | default: 344 | tc::println("未知系统操作"); 345 | } 346 | ``` 347 | 348 | ### ⏱️ 获取系统时间 349 | 350 | | 宏名 | 说明 | 351 | |------|------| 352 | | SYS_YEAR | 年 | 353 | | SYS_MONTH | 月 | 354 | | SYS_DAY | 日 | 355 | | SYS_HOUR | 时 | 356 | | SYS_MINUTE | 分 | 357 | | SYS_SECOND | 秒 | 358 | | SYS_TIMESTAMP | Unix时间戳(默认) | 359 | 360 | ```cpp 361 | int year = tc::getSystemTime(SYS_YEAR); 362 | int timestamp = tc::getSystemTime(); // Unix时间戳 363 | ``` 364 | 365 | ### ⌨️ 按键处理 366 | 367 | #### waitKey - 等待按键 368 | 369 | - `tc::waitKey()`:等待任意按键 370 | - `tc::waitKey(char key)` / `tc::waitKey(int key)`:等待特定按键(如 tc::waitKey('A')、tc::waitKey(KEY_ESC)) 371 | 372 | ```cpp 373 | tc::waitKey(); // 等待任意键 374 | // 等待按下A键 375 | tc::waitKey('A'); 376 | // 等待ESC键 377 | tc::waitKey(KEY_ESC); 378 | ``` 379 | 380 | #### isKeyPressed - 检测按键状态 381 | 382 | - `tc::isKeyPressed(char key)` / `tc::isKeyPressed(int key)`:检测指定按键是否被按下 383 | 384 | ```cpp 385 | // 检测ESC键是否被按下 386 | if (tc::isKeyPressed(KEY_ESC)) { 387 | std::cout << "ESC键被按下" << std::endl; 388 | } 389 | 390 | // 检测方向键 391 | if (tc::isKeyPressed(KEY_UP)) { 392 | std::cout << "上方向键被按下" << std::endl; 393 | } 394 | 395 | // 检测字母键 396 | if (tc::isKeyPressed('A') || tc::isKeyPressed('a')) { 397 | std::cout << "A键被按下" << std::endl; 398 | } 399 | ``` 400 | 401 | #### 常用特殊按键宏 402 | 403 | | 宏名 | 说明 | 404 | |------|------| 405 | | KEY_ESC | ESC | 406 | | KEY_SPACE | 空格 | 407 | | KEY_ENTER | 回车 | 408 | | KEY_TAB | Tab | 409 | | KEY_BACKSPACE| 退格 | 410 | | KEY_INSERT | Insert | 411 | | KEY_DELETE | Delete | 412 | | KEY_HOME | Home | 413 | | KEY_END | End | 414 | | KEY_PAGEUP | PageUp | 415 | | KEY_PAGEDOWN | PageDown | 416 | | KEY_UP | 上方向键 | 417 | | KEY_DOWN | 下方向键 | 418 | | KEY_LEFT | 左方向键 | 419 | | KEY_RIGHT | 右方向键 | 420 | | KEY_F1 ~ KEY_F12 | F1~F12 功能键 | 421 | 422 | --- 423 | 424 | ## 🛠️ 编译 425 | 426 | - Windows: `g++ -std=c++17 test.cpp -o test.exe` 427 | - Linux/macOS: `g++ -std=c++17 -pthread test.cpp -o test` 428 | 429 | --- 430 | 431 | ## 📄 协议 432 | 433 | MIT 434 | 435 | --- 436 | 437 | ## 🌐 联系 438 | 439 | - 📥 电子邮件: -------------------------------------------------------------------------------- /doc/tc_key_handling.md: -------------------------------------------------------------------------------- 1 | # TC.hpp 按键处理参考 2 | 3 | 本文档详细介绍了 TC.hpp 库中的按键处理功能,包括按键等待、按键检测和特殊按键处理。 4 | 5 | ## 目录 6 | 7 | - [按键宏定义](#按键宏定义) 8 | - [基本按键等待](#基本按键等待) 9 | - [特殊按键处理](#特殊按键处理) 10 | - [按键检测](#按键检测) 11 | - [实时按键处理](#实时按键处理) 12 | - [跨平台兼容性](#跨平台兼容性) 13 | - [常见问题与解决方案](#常见问题与解决方案) 14 | - [使用示例](#使用示例) 15 | 16 | ## 按键宏定义 17 | 18 | TC.hpp 提供了一系列按键宏定义,方便在代码中使用: 19 | 20 | ```cpp 21 | // 基本按键 22 | #define KEY_ESC 27 // ESC键 23 | #define KEY_SPACE 32 // 空格键 24 | #define KEY_ENTER 13 // 回车键 25 | #define KEY_TAB 9 // Tab键 26 | #define KEY_BACKSPACE 8 // 退格键 27 | 28 | // 功能键 29 | #define KEY_INSERT 0x2D // Insert键 30 | #define KEY_DELETE 0x2E // Delete键 31 | #define KEY_HOME 0x24 // Home键 32 | #define KEY_END 0x23 // End键 33 | #define KEY_PAGEUP 0x21 // PageUp键 34 | #define KEY_PAGEDOWN 0x22 // PageDown键 35 | 36 | // 方向键 37 | #define KEY_UP 0x26 // 上方向键 38 | #define KEY_DOWN 0x28 // 下方向键 39 | #define KEY_LEFT 0x25 // 左方向键 40 | #define KEY_RIGHT 0x27 // 右方向键 41 | 42 | // 功能键F1-F12 43 | #define KEY_F1 0x70 // F1键 44 | #define KEY_F2 0x71 // F2键 45 | #define KEY_F3 0x72 // F3键 46 | #define KEY_F4 0x73 // F4键 47 | #define KEY_F5 0x74 // F5键 48 | #define KEY_F6 0x75 // F6键 49 | #define KEY_F7 0x76 // F7键 50 | #define KEY_F8 0x77 // F8键 51 | #define KEY_F9 0x78 // F9键 52 | #define KEY_F10 0x79 // F10键 53 | #define KEY_F11 0x7A // F11键 54 | #define KEY_F12 0x7B // F12键 55 | ``` 56 | 57 | ## 基本按键等待 58 | 59 | TC.hpp 提供了三种形式的按键等待函数: 60 | 61 | ```cpp 62 | // 等待任意按键 63 | tc::waitKey(); 64 | 65 | // 等待特定字符键 66 | tc::waitKey('A'); // 等待按下A键 67 | 68 | // 等待特殊按键 69 | tc::waitKey(KEY_ESC); // 等待按下ESC键 70 | tc::waitKey(KEY_ENTER); // 等待按下回车键 71 | ``` 72 | 73 | ## 特殊按键处理 74 | 75 | TC.hpp 在 Windows 平台上对特殊按键(如方向键、功能键等)进行了特殊处理,确保它们能够正确识别。在 Windows 系统中,这些特殊按键通常会生成两个字符:一个前缀字符(0 或 224)和一个扩展键码。TC.hpp 的 `waitKey` 函数会自动处理这种情况,将扩展键码转换为对应的宏定义值。 76 | 77 | ```cpp 78 | // Windows平台上的waitKey实现(简化版) 79 | inline void waitKey(int key) { 80 | int ch; 81 | do { 82 | ch = _getch(); 83 | // 处理特殊键(方向键等) 84 | if (ch == 0 || ch == 224) { 85 | ch = _getch(); 86 | // 将扩展键转换为我们定义的键码 87 | switch (ch) { 88 | case 72: ch = KEY_UP; break; // 上方向键 89 | case 80: ch = KEY_DOWN; break; // 下方向键 90 | case 75: ch = KEY_LEFT; break; // 左方向键 91 | case 77: ch = KEY_RIGHT; break; // 右方向键 92 | // 其他特殊键... 93 | } 94 | } 95 | } while (ch != key); 96 | } 97 | ``` 98 | 99 | ## 按键检测 100 | 101 | 在游戏或交互式应用中,通常需要检测是否有按键按下,而不是等待按键。TC.hpp 可以与 `_kbhit()` 函数结合使用来实现这一功能: 102 | 103 | ```cpp 104 | #include "tc.hpp" 105 | #include // 对于Windows平台,需要包含此头文件 106 | 107 | void checkKeyPress() { 108 | if (_kbhit()) { // 检查是否有按键按下 109 | int key = _getch(); 110 | 111 | // 处理特殊键(方向键等) 112 | if (key == 0 || key == 224) { 113 | key = _getch(); 114 | switch (key) { 115 | case 72: tc::println("上方向键被按下"); break; 116 | case 80: tc::println("下方向键被按下"); break; 117 | case 75: tc::println("左方向键被按下"); break; 118 | case 77: tc::println("右方向键被按下"); break; 119 | default: tc::println("其他特殊键: ", key); 120 | } 121 | } else { 122 | tc::println("普通键被按下: ", key, " (", (char)key, ")"); 123 | } 124 | } 125 | } 126 | ``` 127 | 128 | ## 实时按键处理 129 | 130 | 在游戏循环中处理按键: 131 | 132 | ```cpp 133 | #include "tc.hpp" 134 | #include 135 | 136 | int main() { 137 | tc::printer().clear(); 138 | tc::println("使用方向键移动,按ESC退出"); 139 | 140 | int x = 10, y = 10; 141 | bool running = true; 142 | 143 | tc::printer().hideCursor(); 144 | 145 | while (running) { 146 | // 清除当前位置 147 | tc::printer().moveCursor(x, y); 148 | tc::print(" "); 149 | 150 | // 检查按键 151 | if (_kbhit()) { 152 | int key = _getch(); 153 | 154 | // 处理ESC键 155 | if (key == KEY_ESC) { 156 | running = false; 157 | continue; 158 | } 159 | 160 | // 处理特殊键 161 | if (key == 0 || key == 224) { 162 | key = _getch(); 163 | switch (key) { 164 | case 72: y = (y > 1) ? y - 1 : y; break; // 上 165 | case 80: y = (y < 20) ? y + 1 : y; break; // 下 166 | case 75: x = (x > 1) ? x - 1 : x; break; // 左 167 | case 77: x = (x < 30) ? x + 1 : x; break; // 右 168 | } 169 | } 170 | } 171 | 172 | // 绘制新位置 173 | tc::printer().moveCursor(x, y); 174 | tc::print(TCOLOR_GREEN, "@", TCOLOR_RESET); 175 | 176 | // 短暂延时 177 | tc::wait(0.05); 178 | } 179 | 180 | tc::printer().showCursor(); 181 | tc::printer().moveCursor(1, 22); 182 | tc::println("程序结束"); 183 | 184 | return 0; 185 | } 186 | ``` 187 | 188 | ## 跨平台兼容性 189 | 190 | TC.hpp 的按键处理在不同平台上的实现方式: 191 | 192 | - **Windows**: 使用 `_getch()` 函数捕获按键,并对扩展键进行特殊处理 193 | - **Linux/macOS**: 使用 `termios` 库修改终端属性,实现无缓冲的按键捕获 194 | 195 | 库会自动检测平台并使用适当的实现,无需用户手动配置。 196 | 197 | ```cpp 198 | // Linux/macOS平台上的waitKey实现(简化版) 199 | #include 200 | inline void waitKey() { 201 | termios oldt, newt; 202 | tcgetattr(0, &oldt); 203 | newt = oldt; 204 | newt.c_lflag &= ~ICANON; 205 | tcsetattr(0, TCSANOW, &newt); 206 | getchar(); 207 | tcsetattr(0, TCSANOW, &oldt); 208 | } 209 | ``` 210 | 211 | ## 常见问题与解决方案 212 | 213 | ### 1. 方向键无法正确识别 214 | 215 | 如果方向键无法正确识别,可能是因为扩展键处理有问题。确保使用最新版本的 TC.hpp,其中包含了对扩展键的完整支持。 216 | 217 | ### 2. 功能键(F1-F12)无法正确识别 218 | 219 | 功能键在不同终端和平台上的行为可能不同。TC.hpp 已经对常见平台进行了适配,但如果遇到问题,可以使用以下代码来调试按键码: 220 | 221 | ```cpp 222 | #include "tc.hpp" 223 | #include 224 | 225 | int main() { 226 | tc::println("按键测试 - 按任意键查看键码,按ESC退出"); 227 | 228 | while (true) { 229 | int key = _getch(); 230 | tc::print("按键码: ", key); 231 | 232 | if (key == 0 || key == 224) { 233 | key = _getch(); 234 | tc::println(" (扩展键: ", key, ")"); 235 | } else { 236 | tc::println(); 237 | if (key == KEY_ESC) break; 238 | } 239 | } 240 | 241 | return 0; 242 | } 243 | ``` 244 | 245 | ### 3. 在Linux/macOS上使用_kbhit() 246 | 247 | `_kbhit()` 是Windows特有的函数。在Linux/macOS上,可以使用以下替代方案: 248 | 249 | ```cpp 250 | #include 251 | #include 252 | #include 253 | 254 | // Linux/macOS上的_kbhit()替代实现 255 | int _kbhit() { 256 | struct termios oldt, newt; 257 | int ch; 258 | int oldf; 259 | 260 | tcgetattr(STDIN_FILENO, &oldt); 261 | newt = oldt; 262 | newt.c_lflag &= ~(ICANON | ECHO); 263 | tcsetattr(STDIN_FILENO, TCSANOW, &newt); 264 | oldf = fcntl(STDIN_FILENO, F_GETFL, 0); 265 | fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); 266 | 267 | ch = getchar(); 268 | 269 | tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 270 | fcntl(STDIN_FILENO, F_SETFL, oldf); 271 | 272 | if(ch != EOF) { 273 | ungetc(ch, stdin); 274 | return 1; 275 | } 276 | 277 | return 0; 278 | } 279 | ``` 280 | 281 | ## 使用示例 282 | 283 | ### 示例1:等待特定按键 284 | 285 | ```cpp 286 | #include "tc.hpp" 287 | 288 | int main() { 289 | tc::println("按键测试"); 290 | tc::println("======="); 291 | 292 | tc::println("\n按 ESC 键退出..."); 293 | tc::waitKey(KEY_ESC); 294 | tc::println("检测到 ESC 键"); 295 | 296 | tc::println("\n按方向键测试:"); 297 | tc::println("按上方向键..."); 298 | tc::waitKey(KEY_UP); 299 | tc::println("检测到上方向键"); 300 | 301 | tc::println("按下方向键..."); 302 | tc::waitKey(KEY_DOWN); 303 | tc::println("检测到下方向键"); 304 | 305 | tc::println("按左方向键..."); 306 | tc::waitKey(KEY_LEFT); 307 | tc::println("检测到左方向键"); 308 | 309 | tc::println("按右方向键..."); 310 | tc::waitKey(KEY_RIGHT); 311 | tc::println("检测到右方向键"); 312 | 313 | return 0; 314 | } 315 | ``` 316 | 317 | ### 示例2:实时按键控制 318 | 319 | ```cpp 320 | #include "tc.hpp" 321 | #include 322 | 323 | int main() { 324 | tc::printer().clear(); 325 | tc::println(TCOLOR_CYAN, "按键控制示例", TCOLOR_RESET); 326 | tc::println("使用方向键移动 '@',按 ESC 退出"); 327 | 328 | int x = 10, y = 5; 329 | bool running = true; 330 | 331 | tc::printer().hideCursor(); 332 | 333 | // 绘制边界 334 | for (int i = 0; i < 20; ++i) { 335 | tc::printer().moveCursor(0, i); 336 | tc::print("#"); 337 | tc::printer().moveCursor(30, i); 338 | tc::print("#"); 339 | } 340 | 341 | for (int i = 0; i < 31; ++i) { 342 | tc::printer().moveCursor(i, 0); 343 | tc::print("#"); 344 | tc::printer().moveCursor(i, 19); 345 | tc::print("#"); 346 | } 347 | 348 | while (running) { 349 | // 清除当前位置 350 | tc::printer().moveCursor(x, y); 351 | tc::print(" "); 352 | 353 | // 检查按键 354 | if (_kbhit()) { 355 | int key = _getch(); 356 | 357 | // 处理ESC键 358 | if (key == KEY_ESC) { 359 | running = false; 360 | continue; 361 | } 362 | 363 | // 处理特殊键 364 | if (key == 0 || key == 224) { 365 | key = _getch(); 366 | switch (key) { 367 | case 72: // 上 368 | if (y > 1) y--; 369 | break; 370 | case 80: // 下 371 | if (y < 18) y++; 372 | break; 373 | case 75: // 左 374 | if (x > 1) x--; 375 | break; 376 | case 77: // 右 377 | if (x < 29) x++; 378 | break; 379 | } 380 | } 381 | } 382 | 383 | // 绘制新位置 384 | tc::printer().moveCursor(x, y); 385 | tc::print(TCOLOR_GREEN, "@", TCOLOR_RESET); 386 | 387 | // 显示坐标 388 | tc::printer().moveCursor(32, 5); 389 | tc::print("位置: (", x, ",", y, ") "); 390 | 391 | // 短暂延时 392 | tc::wait(0.05); 393 | } 394 | 395 | tc::printer().showCursor(); 396 | tc::printer().moveCursor(0, 21); 397 | tc::println("\n程序结束"); 398 | 399 | return 0; 400 | } 401 | ``` 402 | 403 | ### 示例3:按键调试工具 404 | 405 | ```cpp 406 | #include "tc.hpp" 407 | #include 408 | #include 409 | 410 | std::string getKeyName(int key) { 411 | switch (key) { 412 | case KEY_ESC: return "ESC"; 413 | case KEY_SPACE: return "SPACE"; 414 | case KEY_ENTER: return "ENTER"; 415 | case KEY_TAB: return "TAB"; 416 | case KEY_BACKSPACE: return "BACKSPACE"; 417 | case KEY_INSERT: return "INSERT"; 418 | case KEY_DELETE: return "DELETE"; 419 | case KEY_HOME: return "HOME"; 420 | case KEY_END: return "END"; 421 | case KEY_PAGEUP: return "PAGE UP"; 422 | case KEY_PAGEDOWN: return "PAGE DOWN"; 423 | case KEY_UP: return "UP ARROW"; 424 | case KEY_DOWN: return "DOWN ARROW"; 425 | case KEY_LEFT: return "LEFT ARROW"; 426 | case KEY_RIGHT: return "RIGHT ARROW"; 427 | case KEY_F1: return "F1"; 428 | case KEY_F2: return "F2"; 429 | case KEY_F3: return "F3"; 430 | case KEY_F4: return "F4"; 431 | case KEY_F5: return "F5"; 432 | case KEY_F6: return "F6"; 433 | case KEY_F7: return "F7"; 434 | case KEY_F8: return "F8"; 435 | case KEY_F9: return "F9"; 436 | case KEY_F10: return "F10"; 437 | case KEY_F11: return "F11"; 438 | case KEY_F12: return "F12"; 439 | default: return "UNKNOWN"; 440 | } 441 | } 442 | 443 | int main() { 444 | tc::printer().clear(); 445 | tc::println(TCOLOR_CYAN, TFONT_BOLD, "按键调试工具", TCOLOR_RESET); 446 | tc::println(TCOLOR_CYAN, "==========", TCOLOR_RESET); 447 | tc::println("\n按任意键查看键码,按 ESC 键退出...\n"); 448 | 449 | while (true) { 450 | int key = _getch(); 451 | 452 | if (key == KEY_ESC) { 453 | tc::println(TCOLOR_YELLOW, "检测到 ESC 键,程序退出", TCOLOR_RESET); 454 | break; 455 | } 456 | 457 | tc::print(TCOLOR_GREEN, "按键码: ", TCOLOR_RESET, key); 458 | 459 | if (key == 0 || key == 224) { 460 | int extKey = _getch(); 461 | tc::print(" (扩展键: ", extKey, ")"); 462 | 463 | // 转换扩展键码为我们的键码 464 | int mappedKey = 0; 465 | switch (extKey) { 466 | case 72: mappedKey = KEY_UP; break; 467 | case 80: mappedKey = KEY_DOWN; break; 468 | case 75: mappedKey = KEY_LEFT; break; 469 | case 77: mappedKey = KEY_RIGHT; break; 470 | case 71: mappedKey = KEY_HOME; break; 471 | case 79: mappedKey = KEY_END; break; 472 | case 73: mappedKey = KEY_PAGEUP; break; 473 | case 81: mappedKey = KEY_PAGEDOWN; break; 474 | case 82: mappedKey = KEY_INSERT; break; 475 | case 83: mappedKey = KEY_DELETE; break; 476 | case 59: mappedKey = KEY_F1; break; 477 | case 60: mappedKey = KEY_F2; break; 478 | case 61: mappedKey = KEY_F3; break; 479 | case 62: mappedKey = KEY_F4; break; 480 | case 63: mappedKey = KEY_F5; break; 481 | case 64: mappedKey = KEY_F6; break; 482 | case 65: mappedKey = KEY_F7; break; 483 | case 66: mappedKey = KEY_F8; break; 484 | case 67: mappedKey = KEY_F9; break; 485 | case 68: mappedKey = KEY_F10; break; 486 | case 133: mappedKey = KEY_F11; break; 487 | case 134: mappedKey = KEY_F12; break; 488 | } 489 | 490 | if (mappedKey != 0) { 491 | tc::print(" -> TC键码: ", mappedKey, " (", getKeyName(mappedKey), ")"); 492 | } 493 | } else if (key >= 32 && key <= 126) { 494 | // 可打印字符 495 | tc::print(" (字符: '", (char)key, "')"); 496 | } else { 497 | // 检查是否是我们定义的键码 498 | std::string keyName = getKeyName(key); 499 | if (keyName != "UNKNOWN") { 500 | tc::print(" (", keyName, ")"); 501 | } 502 | } 503 | 504 | tc::println(); 505 | } 506 | 507 | return 0; 508 | } 509 | ``` 510 | 511 | --- 512 | 513 | 本文档提供了 TC.hpp 库中按键处理功能的详细参考。通过这些功能,您可以轻松实现各种交互式应用程序,如游戏、菜单系统和命令行界面。 514 | -------------------------------------------------------------------------------- /doc/tc_color_functions.md: -------------------------------------------------------------------------------- 1 | # TC库颜色控制功能详解 2 | 3 | 本文档详细说明了TC库中与颜色控制相关的各种接口和功能。TC库提供了多种方式来设置终端文本的颜色和样式,包括宏定义、颜色控制类和便捷函数。 4 | 5 | ## 目录 6 | 7 | 1. [概述](#概述) 8 | 2. [全局颜色宏](#全局颜色宏) 9 | 3. [ColorController类](#colorcontroller类) 10 | 4. [颜色包装器类](#颜色包装器类) 11 | 5. [便捷颜色函数](#便捷颜色函数) 12 | 6. [Windows平台特定功能](#windows平台特定功能) 13 | 7. [使用建议](#使用建议) 14 | 8. [示例代码](#示例代码) 15 | 16 | ## 概述 17 | 18 | TC库提供了多种方式来控制终端文本的颜色和样式: 19 | 20 | 1. **全局颜色宏**:直接在流式输出中使用的ANSI颜色和样式宏。 21 | 2. **ColorController类**:提供统一的颜色和样式设置接口。 22 | 3. **颜色包装器类**:用于在流式输出中方便地设置颜色。 23 | 4. **便捷颜色函数**:返回已着色的字符串。 24 | 5. **Windows平台特定功能**:针对Windows控制台的特殊支持。 25 | 26 | ## 全局颜色宏 27 | 28 | TC库定义了一系列全局宏,可以直接在流式输出中使用: 29 | 30 | ### 前景色宏 31 | 32 | | 宏名称 | 描述 | 33 | |--------|------| 34 | | `TCOLOR_BLACK` | 黑色文本 | 35 | | `TCOLOR_RED` | 红色文本 | 36 | | `TCOLOR_GREEN` | 绿色文本 | 37 | | `TCOLOR_YELLOW` | 黄色文本 | 38 | | `TCOLOR_BLUE` | 蓝色文本 | 39 | | `TCOLOR_MAGENTA` | 洋红色文本 | 40 | | `TCOLOR_CYAN` | 青色文本 | 41 | | `TCOLOR_WHITE` | 白色文本 | 42 | | `TCOLOR_DEFAULT` | 默认前景色 | 43 | | `TCOLOR_RESET` | 重置所有属性 | 44 | 45 | ### 背景色宏 46 | 47 | | 宏名称 | 描述 | 48 | |--------|------| 49 | | `BCOLOR_BLACK` | 黑色背景 | 50 | | `BCOLOR_RED` | 红色背景 | 51 | | `BCOLOR_GREEN` | 绿色背景 | 52 | | `BCOLOR_YELLOW` | 黄色背景 | 53 | | `BCOLOR_BLUE` | 蓝色背景 | 54 | | `BCOLOR_MAGENTA` | 洋红色背景 | 55 | | `BCOLOR_CYAN` | 青色背景 | 56 | | `BCOLOR_WHITE` | 白色背景 | 57 | | `BCOLOR_DEFAULT` | 默认背景色 | 58 | 59 | ### 字体样式宏 60 | 61 | | 宏名称 | 描述 | 62 | |--------|------| 63 | | `TFONT_BOLD` | 粗体/加粗文本 | 64 | | `TFONT_FAINT` | 微弱/淡色文本 | 65 | | `TFONT_ITALIC` | 斜体文本 | 66 | | `TFONT_UNDERLINE` | 下划线文本 | 67 | | `TFONT_BLINK_SLOW` | 慢速闪烁文本 | 68 | | `TFONT_BLINK_FAST` | 快速闪烁文本 | 69 | | `TFONT_REVERSE` | 反色(前景背景互换) | 70 | | `TFONT_CONCEAL` | 隐藏文本 | 71 | | `TFONT_CROSSED` | 删除线文本 | 72 | | `TFONT_DEFAULT` | 默认字体 | 73 | | `TFONT_RESET` | 全部重置(所有属性) | 74 | 75 | ### RGB颜色宏 76 | 77 | | 宏名称 | 描述 | 78 | |--------|------| 79 | | `TCOLOR_RGB(r, g, b)` | 使用RGB值设置文本颜色 | 80 | 81 | ### 使用示例 82 | 83 | ```cpp 84 | std::cout << TCOLOR_RED << "红色文本" << TCOLOR_RESET << std::endl; 85 | std::cout << BCOLOR_BLUE << "蓝色背景" << TCOLOR_RESET << std::endl; 86 | std::cout << TFONT_BOLD << "粗体文本" << TFONT_RESET << std::endl; 87 | std::cout << TCOLOR_RGB(255, 128, 0) << "橙色文本" << TCOLOR_RESET << std::endl; 88 | ``` 89 | 90 | ## ColorController类 91 | 92 | `tc::ColorController`类提供了统一的颜色和样式设置接口,在不同平台上使用相应的实现。 93 | 94 | ### 颜色枚举 95 | 96 | `tc::ColorController::Color`枚举定义了支持的所有颜色: 97 | 98 | | 枚举值 | 描述 | 99 | |--------|------| 100 | | `BLACK` | 黑色 | 101 | | `RED` | 红色 | 102 | | `GREEN` | 绿色 | 103 | | `YELLOW` | 黄色 | 104 | | `BLUE` | 蓝色 | 105 | | `MAGENTA` | 洋红色 | 106 | | `CYAN` | 青色 | 107 | | `WHITE` | 白色 | 108 | | `BRIGHT_BLACK` | 亮黑色/灰色 | 109 | | `BRIGHT_RED` | 亮红色 | 110 | | `BRIGHT_GREEN` | 亮绿色 | 111 | | `BRIGHT_YELLOW` | 亮黄色 | 112 | | `BRIGHT_BLUE` | 亮蓝色 | 113 | | `BRIGHT_MAGENTA` | 亮洋红色 | 114 | | `BRIGHT_CYAN` | 亮青色 | 115 | | `BRIGHT_WHITE` | 亮白色 | 116 | | `RESET` | 重置为默认颜色 | 117 | 118 | ### 静态方法 119 | 120 | | 方法名 | 描述 | 参数 | 返回值 | 121 | |--------|------|------|--------| 122 | | `setColor(Color color)` | 设置控制台文本颜色 | `color`: 要设置的颜色 | 无 | 123 | | `setRGBColor(int r, int g, int b)` | 设置RGB颜色 | `r`, `g`, `b`: RGB分量(0-255) | 无 | 124 | | `setBold(bool enable)` | 设置文本粗体样式 | `enable`: 是否启用粗体 | 无 | 125 | 126 | ### 使用示例 127 | 128 | ```cpp 129 | // 设置红色文本 130 | tc::ColorController::setColor(tc::ColorController::Color::RED); 131 | std::cout << "红色文本" << std::endl; 132 | 133 | // 设置RGB颜色 134 | tc::ColorController::setRGBColor(255, 128, 0); 135 | std::cout << "橙色文本" << std::endl; 136 | 137 | // 设置粗体 138 | tc::ColorController::setBold(true); 139 | std::cout << "粗体文本" << std::endl; 140 | 141 | // 重置颜色 142 | tc::ColorController::setColor(tc::ColorController::Color::RESET); 143 | ``` 144 | 145 | ## 颜色包装器类 146 | 147 | TC库提供了几个包装器类,用于在流式输出中方便地设置颜色和样式。 148 | 149 | ### ColorWrapper类 150 | 151 | `tc::ColorWrapper`类封装了颜色设置,便于在流式输出中使用。 152 | 153 | ```cpp 154 | std::cout << tc::ColorWrapper(tc::ColorController::Color::RED) << "红色文本" 155 | << tc::ColorWrapper(tc::ColorController::Color::RESET) << std::endl; 156 | ``` 157 | 158 | ### RGBColorWrapper类 159 | 160 | `tc::RGBColorWrapper`类封装了RGB颜色设置,便于在流式输出中使用。 161 | 162 | ```cpp 163 | std::cout << tc::RGBColorWrapper(255, 128, 0) << "橙色文本" 164 | << tc::ColorWrapper(tc::ColorController::Color::RESET) << std::endl; 165 | ``` 166 | 167 | ### FontStyleWrapper类 168 | 169 | `tc::FontStyleWrapper`类封装了字体样式设置(目前支持粗体),便于在流式输出中使用。 170 | 171 | ```cpp 172 | std::cout << tc::FontStyleWrapper(true) << "粗体文本" 173 | << tc::FontStyleWrapper(false) << std::endl; 174 | ``` 175 | 176 | ## 便捷颜色函数 177 | 178 | TC库提供了一系列便捷函数,用于为文本添加颜色,返回已着色的字符串。 179 | 180 | ### 基本颜色函数 181 | 182 | | 函数名 | 描述 | 参数 | 返回值 | 183 | |--------|------|------|--------| 184 | | `colorize(text, color)` | 为文本添加指定颜色 | `text`: 要着色的文本
`color`: 要应用的颜色 | 带有颜色代码的字符串 | 185 | | `colorizeRGB(text, r, g, b)` | 为文本添加RGB颜色 | `text`: 要着色的文本
`r`, `g`, `b`: RGB分量(0-255) | 带有RGB颜色代码的字符串 | 186 | 187 | ### 标准颜色函数 188 | 189 | | 函数名 | 描述 | 参数 | 返回值 | 190 | |--------|------|------|--------| 191 | | `red(text)` | 为文本添加红色 | `text`: 要着色的文本 | 红色文本字符串 | 192 | | `green(text)` | 为文本添加绿色 | `text`: 要着色的文本 | 绿色文本字符串 | 193 | | `blue(text)` | 为文本添加蓝色 | `text`: 要着色的文本 | 蓝色文本字符串 | 194 | | `yellow(text)` | 为文本添加黄色 | `text`: 要着色的文本 | 黄色文本字符串 | 195 | | `cyan(text)` | 为文本添加青色 | `text`: 要着色的文本 | 青色文本字符串 | 196 | | `magenta(text)` | 为文本添加洋红色 | `text`: 要着色的文本 | 洋红色文本字符串 | 197 | | `white(text)` | 为文本添加白色 | `text`: 要着色的文本 | 白色文本字符串 | 198 | 199 | ### 亮色函数 200 | 201 | | 函数名 | 描述 | 参数 | 返回值 | 202 | |--------|------|------|--------| 203 | | `brightRed(text)` | 为文本添加亮红色 | `text`: 要着色的文本 | 亮红色文本字符串 | 204 | | `brightGreen(text)` | 为文本添加亮绿色 | `text`: 要着色的文本 | 亮绿色文本字符串 | 205 | | `brightBlue(text)` | 为文本添加亮蓝色 | `text`: 要着色的文本 | 亮蓝色文本字符串 | 206 | | `brightYellow(text)` | 为文本添加亮黄色 | `text`: 要着色的文本 | 亮黄色文本字符串 | 207 | | `brightCyan(text)` | 为文本添加亮青色 | `text`: 要着色的文本 | 亮青色文本字符串 | 208 | | `brightMagenta(text)` | 为文本添加亮洋红色 | `text`: 要着色的文本 | 亮洋红色文本字符串 | 209 | | `brightWhite(text)` | 为文本添加亮白色 | `text`: 要着色的文本 | 亮白色文本字符串 | 210 | 211 | > ⚠ 注意:便捷颜色函数实际上是为文本添加ANSI转义序列,因此仅适用于支持ANSI转义序列的终端显示。如果你有在低于 Windows 10 的命令提示符等终端上的显示需求,请不用使用这些函数。 212 | 213 | ### 使用示例 214 | 215 | ```cpp 216 | // 使用colorize函数 217 | std::string coloredText = tc::colorize("彩色文本", tc::ColorController::Color::CYAN); 218 | std::cout << coloredText << std::endl; 219 | 220 | // 使用colorizeRGB函数 221 | std::string rgbText = tc::colorizeRGB("RGB颜色文本", 255, 128, 0); 222 | std::cout << rgbText << std::endl; 223 | 224 | // 使用标准颜色函数 225 | std::cout << tc::red("红色文本") << std::endl; 226 | std::cout << tc::green("绿色文本") << std::endl; 227 | std::cout << tc::blue("蓝色文本") << std::endl; 228 | std::cout << tc::yellow("黄色文本") << std::endl; 229 | std::cout << tc::cyan("青色文本") << std::endl; 230 | std::cout << tc::magenta("洋红色文本") << std::endl; 231 | std::cout << tc::white("白色文本") << std::endl; 232 | 233 | // 使用亮色函数 234 | std::cout << tc::brightRed("亮红色文本") << std::endl; 235 | std::cout << tc::brightGreen("亮绿色文本") << std::endl; 236 | std::cout << tc::brightBlue("亮蓝色文本") << std::endl; 237 | std::cout << tc::brightYellow("亮黄色文本") << std::endl; 238 | ``` 239 | 240 | ## Windows平台特定功能 241 | 242 | 在Windows平台上,TC库提供了额外的功能来支持Windows控制台。 243 | 244 | ### Win32Console类 245 | 246 | `tc::Win32Console`类封装了Windows控制台API的操作,提供颜色设置、光标控制、清屏等功能。采用单例模式设计。 247 | 248 | | 方法名 | 描述 | 参数 | 返回值 | 249 | |--------|------|------|--------| 250 | | `getInstance()` | 获取单例实例 | 无 | `Win32Console&`: 单例引用 | 251 | | `isInitialized()` | 判断控制台是否成功初始化 | 无 | `bool`: 初始化状态 | 252 | | `setColor(WORD color)` | 设置控制台文本颜色 | `color`: Windows控制台颜色属性 | 无 | 253 | | `pushColor(WORD color)` | 保存当前颜色并设置新颜色 | `color`: 要设置的新颜色 | 无 | 254 | | `popColor()` | 恢复之前保存的颜色 | 无 | 无 | 255 | | `resetColor()` | 重置为原始控制台颜色 | 无 | 无 | 256 | | `getCurrentColor()` | 获取当前控制台颜色 | 无 | `WORD`: 当前颜色属性 | 257 | | `moveCursor(int x, int y)` | 移动控制台光标到指定位置 | `x`: 列坐标(从0开始)
`y`: 行坐标(从0开始) | 无 | 258 | | `clearScreen()` | 清空控制台屏幕 | 无 | 无 | 259 | | `getConsoleSize()` | 获取控制台窗口大小 | 无 | `std::pair`: 包含宽度和高度的对组 | 260 | | `rgbToWin32Color(int r, int g, int b)` | 将RGB颜色近似转换为Windows控制台16色 | `r`, `g`, `b`: RGB分量(0-255) | `WORD`: Windows控制台颜色属性 | 261 | 262 | ### win32_colors命名空间 263 | 264 | `tc::win32_colors`命名空间定义了Windows控制台API使用的颜色常量。 265 | 266 | | 常量名 | 描述 | 267 | |--------|------| 268 | | `BLACK` | 黑色 | 269 | | `DARK_BLUE` | 深蓝色 | 270 | | `DARK_GREEN` | 深绿色 | 271 | | `DARK_CYAN` | 深青色 | 272 | | `DARK_RED` | 深红色 | 273 | | `DARK_MAGENTA` | 深洋红色 | 274 | | `DARK_YELLOW` | 深黄色 | 275 | | `GRAY` | 灰色 | 276 | | `DARK_GRAY` | 深灰色 | 277 | | `BLUE` | 蓝色 | 278 | | `GREEN` | 绿色 | 279 | | `CYAN` | 青色 | 280 | | `RED` | 红色 | 281 | | `MAGENTA` | 洋红色 | 282 | | `YELLOW` | 黄色 | 283 | | `WHITE` | 白色 | 284 | 285 | ### 使用示例 286 | 287 | ```cpp 288 | #ifdef _WIN32 289 | // 获取Win32Console单例 290 | auto& console = tc::Win32Console::getInstance(); 291 | 292 | // 设置颜色 293 | console.setColor(tc::win32_colors::RED); 294 | std::cout << "红色文本" << std::endl; 295 | 296 | // 保存当前颜色,设置新颜色,然后恢复 297 | console.pushColor(tc::win32_colors::GREEN); 298 | std::cout << "绿色文本" << std::endl; 299 | console.popColor(); 300 | std::cout << "恢复之前的颜色" << std::endl; 301 | 302 | // 清屏 303 | console.clearScreen(); 304 | 305 | // 移动光标 306 | console.moveCursor(10, 5); 307 | std::cout << "在位置(10,5)" << std::endl; 308 | 309 | // 获取控制台大小 310 | auto [width, height] = console.getConsoleSize(); 311 | std::cout << "控制台大小: " << width << "x" << height << std::endl; 312 | #endif 313 | ``` 314 | 315 | ## 使用建议 316 | 317 | 1. **简单使用**:对于简单的颜色需求,使用全局颜色宏(如`TCOLOR_RED`)是最直接的方式。 318 | 319 | 2. **跨平台兼容**:使用`tc::ColorController`类或便捷颜色函数(如`tc::red()`)可以确保最佳的跨平台兼容性。 320 | 321 | 3. **流式输出**:在流式输出中,可以使用颜色包装器类(如`tc::ColorWrapper`)或全局颜色宏。 322 | 323 | 4. **字符串处理**:如果需要生成彩色字符串以便后续使用,使用便捷颜色函数(如`tc::colorize()`)。 324 | 325 | 5. **Windows特定功能**:在Windows平台上,如果需要更精细的控制,可以使用`tc::Win32Console`类。 326 | 327 | ## 示例代码 328 | 329 | ### 使用全局颜色宏 330 | 331 | ```cpp 332 | #include "../include/tc.hpp" 333 | #include 334 | 335 | int main() { 336 | std::cout << TCOLOR_RED << "红色文本" << TCOLOR_RESET << std::endl; 337 | std::cout << TCOLOR_GREEN << "绿色文本" << TCOLOR_RESET << std::endl; 338 | std::cout << TCOLOR_BLUE << "蓝色文本" << TCOLOR_RESET << std::endl; 339 | 340 | std::cout << BCOLOR_YELLOW << "黄色背景" << TCOLOR_RESET << std::endl; 341 | 342 | std::cout << TFONT_BOLD << "粗体文本" << TFONT_RESET << std::endl; 343 | std::cout << TFONT_UNDERLINE << "下划线文本" << TFONT_RESET << std::endl; 344 | 345 | std::cout << TCOLOR_RGB(255, 128, 0) << "橙色文本" << TCOLOR_RESET << std::endl; 346 | 347 | return 0; 348 | } 349 | ``` 350 | 351 | ### 使用ColorController类 352 | 353 | ```cpp 354 | #include "../include/tc.hpp" 355 | #include 356 | 357 | int main() { 358 | // 设置红色 359 | tc::ColorController::setColor(tc::ColorController::Color::RED); 360 | std::cout << "红色文本" << std::endl; 361 | 362 | // 设置亮绿色 363 | tc::ColorController::setColor(tc::ColorController::Color::BRIGHT_GREEN); 364 | std::cout << "亮绿色文本" << std::endl; 365 | 366 | // 设置RGB颜色 367 | tc::ColorController::setRGBColor(255, 128, 0); 368 | std::cout << "橙色文本" << std::endl; 369 | 370 | // 设置粗体 371 | tc::ColorController::setBold(true); 372 | std::cout << "粗体文本" << std::endl; 373 | 374 | // 重置所有属性 375 | tc::ColorController::setColor(tc::ColorController::Color::RESET); 376 | std::cout << "正常文本" << std::endl; 377 | 378 | return 0; 379 | } 380 | ``` 381 | 382 | ### 使用颜色包装器类 383 | 384 | ```cpp 385 | #include "../include/tc.hpp" 386 | #include 387 | 388 | int main() { 389 | // 使用ColorWrapper 390 | std::cout << tc::ColorWrapper(tc::ColorController::Color::RED) << "红色文本" 391 | << tc::ColorWrapper(tc::ColorController::Color::RESET) << std::endl; 392 | 393 | // 使用RGBColorWrapper 394 | std::cout << tc::RGBColorWrapper(255, 128, 0) << "橙色文本" 395 | << tc::ColorWrapper(tc::ColorController::Color::RESET) << std::endl; 396 | 397 | // 使用FontStyleWrapper 398 | std::cout << tc::FontStyleWrapper(true) << "粗体文本" 399 | << tc::FontStyleWrapper(false) << std::endl; 400 | 401 | return 0; 402 | } 403 | ``` 404 | 405 | ### 使用便捷颜色函数 406 | 407 | ```cpp 408 | #include "../include/tc.hpp" 409 | #include 410 | 411 | int main() { 412 | // 使用colorize函数 413 | std::string coloredText = tc::colorize("彩色文本", tc::ColorController::Color::CYAN); 414 | std::cout << coloredText << std::endl; 415 | 416 | // 使用便捷颜色函数 417 | std::cout << tc::red("红色文本") << std::endl; 418 | std::cout << tc::green("绿色文本") << std::endl; 419 | std::cout << tc::blue("蓝色文本") << std::endl; 420 | std::cout << tc::yellow("黄色文本") << std::endl; 421 | 422 | return 0; 423 | } 424 | ``` 425 | 426 | ### 综合示例 427 | 428 | ```cpp 429 | #include "../include/tc.hpp" 430 | #include 431 | #include 432 | 433 | void demoGlobalMacros() { 434 | std::cout << "=== 全局颜色宏演示 ===" << std::endl; 435 | 436 | std::cout << TCOLOR_RED << "红色文本" << TCOLOR_RESET << std::endl; 437 | std::cout << BCOLOR_BLUE << "蓝色背景" << TCOLOR_RESET << std::endl; 438 | std::cout << TFONT_BOLD << "粗体文本" << TFONT_RESET << std::endl; 439 | std::cout << TCOLOR_RGB(255, 128, 0) << "橙色文本" << TCOLOR_RESET << std::endl; 440 | 441 | std::cout << TCOLOR_GREEN << "绿色" << TCOLOR_BLUE << "蓝色" << TCOLOR_RESET << std::endl; 442 | 443 | tc::wait(2); 444 | } 445 | 446 | void demoColorController() { 447 | std::cout << "=== ColorController类演示 ===" << std::endl; 448 | 449 | tc::ColorController::setColor(tc::ColorController::Color::RED); 450 | std::cout << "红色文本" << std::endl; 451 | 452 | tc::ColorController::setColor(tc::ColorController::Color::BRIGHT_GREEN); 453 | std::cout << "亮绿色文本" << std::endl; 454 | 455 | tc::ColorController::setRGBColor(255, 128, 0); 456 | std::cout << "橙色文本" << std::endl; 457 | 458 | tc::ColorController::setBold(true); 459 | std::cout << "粗体文本" << std::endl; 460 | 461 | tc::ColorController::setColor(tc::ColorController::Color::RESET); 462 | std::cout << "正常文本" << std::endl; 463 | 464 | tc::wait(2); 465 | } 466 | 467 | void demoColorFunctions() { 468 | std::cout << "=== 便捷颜色函数演示 ===" << std::endl; 469 | 470 | std::cout << tc::red("红色文本") << std::endl; 471 | std::cout << tc::green("绿色文本") << std::endl; 472 | std::cout << tc::blue("蓝色文本") << std::endl; 473 | std::cout << tc::yellow("黄色文本") << std::endl; 474 | 475 | std::string message = "重要提示"; 476 | std::cout << tc::colorize(message, tc::ColorController::Color::BRIGHT_RED) << std::endl; 477 | 478 | tc::wait(2); 479 | } 480 | 481 | int main() { 482 | demoGlobalMacros(); 483 | std::cout << std::endl; 484 | 485 | demoColorController(); 486 | std::cout << std::endl; 487 | 488 | demoColorFunctions(); 489 | std::cout << std::endl; 490 | 491 | std::cout << "所有颜色功能演示完成!" << std::endl; 492 | 493 | return 0; 494 | } 495 | ``` 496 | 497 | 通过以上示例,您可以清楚地了解TC库中各种颜色控制功能的使用方法和区别,从而根据具体需求选择合适的接口。 498 | -------------------------------------------------------------------------------- /doc/tc_api_reference.md: -------------------------------------------------------------------------------- 1 | # TC.hpp API 参考手册 2 | 3 | 本文档提供了 TC.hpp 库的完整 API 参考,包括所有类、函数、宏和常量。 4 | 5 | ## 目录 6 | 7 | - [全局宏](#全局宏) 8 | - [颜色宏](#颜色宏) 9 | - [字体样式宏](#字体样式宏) 10 | - [按键宏](#按键宏) 11 | - [系统相关宏](#系统相关宏) 12 | - [命名空间 tc](#命名空间-tc) 13 | - [输出函数](#输出函数) 14 | - [延时函数](#延时函数) 15 | - [按键等待函数](#按键等待函数) 16 | - [系统相关函数](#系统相关函数) 17 | - [终端控制函数](#终端控制函数) 18 | - [基本终端控制](#基本终端控制) 19 | - [缓冲区控制](#缓冲区控制) 20 | - [类参考](#类参考) 21 | - [PrintProxy 类](#printproxy-类) 22 | - [Printer 类](#printer-类) 23 | - [ColorController 类](#colorcontroller-类) 24 | - [ColorWrapper 类](#colorwrapper-类) 25 | - [RGBColorWrapper 类](#rgbcolorwrapper-类) 26 | - [FontStyleWrapper 类](#fontstylewrapper-类) 27 | - [TSleep 类](#tsleep-类) 28 | - [TSleepStream 类](#tsleepstream-类) 29 | - [ProgressBar 类](#progressbar-类) 30 | - [TOut 类](#tout-类) 31 | - [Win32Console 类](#win32console-类) 32 | 33 | ## 全局宏 34 | 35 | ### 颜色宏 36 | 37 | #### 前景色宏 38 | 39 | | 宏名称 | 描述 | 40 | |--------|------| 41 | | `TCOLOR_BLACK` | 黑色前景色 | 42 | | `TCOLOR_RED` | 红色前景色 | 43 | | `TCOLOR_GREEN` | 绿色前景色 | 44 | | `TCOLOR_YELLOW` | 黄色前景色 | 45 | | `TCOLOR_BLUE` | 蓝色前景色 | 46 | | `TCOLOR_MAGENTA` | 洋红前景色 | 47 | | `TCOLOR_CYAN` | 青色前景色 | 48 | | `TCOLOR_WHITE` | 白色前景色 | 49 | | `TCOLOR_DEFAULT` | 默认前景色 | 50 | | `TCOLOR_RESET` | 重置所有颜色和样式 | 51 | | `TCOLOR_RGB(r, g, b)` | RGB颜色 (0-255) | 52 | 53 | > 在非Windows平台上,这些宏会展开为ANSI转义序列;在Windows平台上,这些宏会被映射到对应的Windows Console API调用。 54 | 55 | #### 背景色宏 56 | 57 | | 宏名称 | 描述 | 58 | |--------|------| 59 | | `BCOLOR_BLACK` | 黑色背景色 | 60 | | `BCOLOR_RED` | 红色背景色 | 61 | | `BCOLOR_GREEN` | 绿色背景色 | 62 | | `BCOLOR_YELLOW` | 黄色背景色 | 63 | | `BCOLOR_BLUE` | 蓝色背景色 | 64 | | `BCOLOR_MAGENTA` | 洋红背景色 | 65 | | `BCOLOR_CYAN` | 青色背景色 | 66 | | `BCOLOR_WHITE` | 白色背景色 | 67 | | `BCOLOR_DEFAULT` | 默认背景色 | 68 | 69 | ### 字体样式宏 70 | 71 | | 宏名称 | 描述 | 72 | |--------|------| 73 | | `TFONT_BOLD` | 粗体/加粗 | 74 | | `TFONT_FAINT` | 微弱/淡色 | 75 | | `TFONT_ITALIC` | 斜体 | 76 | | `TFONT_UNDERLINE` | 下划线 | 77 | | `TFONT_BLINK_SLOW` | 慢速闪烁 | 78 | | `TFONT_BLINK_FAST` | 快速闪烁 | 79 | | `TFONT_REVERSE` | 反色 | 80 | | `TFONT_CONCEAL` | 隐藏 | 81 | | `TFONT_CROSSED` | 删除线 | 82 | | `TFONT_DEFAULT` | 默认字体 | 83 | | `TFONT_FRAKTUR` | Fraktur字体(部分终端支持) | 84 | | `TFONT_DOUBLE_UNDERLINE` | 双下划线/粗体关闭 | 85 | | `TFONT_NORMAL` | 粗体/淡色关闭 | 86 | | `TFONT_NOT_ITALIC` | 关闭斜体/Fraktur | 87 | | `TFONT_NO_UNDERLINE` | 关闭下划线 | 88 | | `TFONT_NO_BLINK` | 关闭闪烁 | 89 | | `TFONT_NO_REVERSE` | 关闭反色 | 90 | | `TFONT_REVEAL` | 关闭隐藏 | 91 | | `TFONT_NOT_CROSSED` | 关闭删除线 | 92 | | `TFONT_THICK` | 粗体(TFONT_BOLD的别名) | 93 | | `TFONT_RESET` | 全部重置 | 94 | 95 | ### 按键宏 96 | 97 | | 宏名称 | 值 | 描述 | 98 | |--------|-----|------| 99 | | `KEY_ESC` | 27 | Escape键 | 100 | | `KEY_SPACE` | 32 | 空格键 | 101 | | `KEY_ENTER` | 13 | 回车键 | 102 | | `KEY_TAB` | 9 | Tab键 | 103 | | `KEY_BACKSPACE` | 8 | 退格键 | 104 | | `KEY_INSERT` | 0x2D | Insert键 | 105 | | `KEY_DELETE` | 0x2E | Delete键 | 106 | | `KEY_HOME` | 0x24 | Home键 | 107 | | `KEY_END` | 0x23 | End键 | 108 | | `KEY_PAGEUP` | 0x21 | Page Up键 | 109 | | `KEY_PAGEDOWN` | 0x22 | Page Down键 | 110 | | `KEY_UP` | 0x26 | 上箭头键 | 111 | | `KEY_DOWN` | 0x28 | 下箭头键 | 112 | | `KEY_LEFT` | 0x25 | 左箭头键 | 113 | | `KEY_RIGHT` | 0x27 | 右箭头键 | 114 | | `KEY_F1` - `KEY_F12` | 0x70 - 0x7B | F1至F12功能键 | 115 | 116 | ### 系统相关宏 117 | 118 | #### 系统时间宏 119 | 120 | | 宏名称 | 值 | 描述 | 121 | |--------|-----|------| 122 | | `SYS_YEAR` | 1 | 年份 | 123 | | `SYS_MONTH` | 2 | 月份(1-12) | 124 | | `SYS_DAY` | 3 | 日期(1-31) | 125 | | `SYS_HOUR` | 4 | 小时(0-23) | 126 | | `SYS_MINUTE` | 5 | 分钟(0-59) | 127 | | `SYS_SECOND` | 6 | 秒钟(0-59) | 128 | | `SYS_TIMESTAMP` | 0 | Unix时间戳 | 129 | 130 | #### 操作系统类型宏 131 | 132 | ##### Windows系列 133 | 134 | | 宏名称 | 值 | 描述 | 135 | |--------|-----|------| 136 | | `OS_WINDOWS` | 100 | 通用Windows标识 | 137 | | `OS_WINDOWSNT6` | 108 | Windows 7/8/8.1 (NT 6.x) | 138 | | `OS_WINDOWSNT10` | 109 | Windows 10 (NT 10.0) | 139 | | `OS_WINDOWSNT11` | 110 | Windows 11 (NT 10.0 build 22000+) | 140 | 141 | ##### Linux发行版 142 | 143 | | 宏名称 | 值 | 描述 | 144 | |--------|-----|------| 145 | | `OS_LINUX` | 200 | 通用Linux标识 | 146 | | `OS_UBUNTU` | 201 | Ubuntu Linux | 147 | | `OS_DEBIAN` | 202 | Debian Linux | 148 | | `OS_FEDORA` | 203 | Fedora Linux | 149 | | `OS_CENTOS` | 204 | CentOS Linux | 150 | | `OS_REDHAT` | 205 | Red Hat Enterprise Linux | 151 | | `OS_SUSE` | 206 | SUSE/openSUSE Linux | 152 | | `OS_ARCH` | 207 | Arch Linux | 153 | | `OS_GENTOO` | 208 | Gentoo Linux | 154 | | `OS_SLACKWARE` | 209 | Slackware Linux | 155 | | `OS_ANDROID` | 210 | Android (基于Linux) | 156 | | `OS_KALI` | 211 | Kali Linux | 157 | | `OS_MINT` | 212 | Linux Mint | 158 | | `OS_MANJARO` | 213 | Manjaro Linux | 159 | | `OS_ALPINE` | 214 | Alpine Linux | 160 | | `OS_RASPBIAN` | 215 | Raspbian | 161 | | `OS_DEEPIN` | 216 | Deepin Linux | 162 | | `OS_ELEMENTARY` | 217 | Elementary OS | 163 | | `OS_ZORIN` | 218 | Zorin OS | 164 | | `OS_POPOS` | 219 | Pop!_OS | 165 | | `OS_CHROMEOS` | 220 | Chrome OS/Chromium OS | 166 | 167 | ##### Apple操作系统 168 | 169 | | 宏名称 | 值 | 描述 | 170 | |--------|-----|------| 171 | | `OS_MACOS` | 300 | 通用macOS标识 | 172 | | `OS_MACOS_HIGHSIERRA` | 324 | macOS 10.13 High Sierra (2017) | 173 | | `OS_MACOS_MOJAVE` | 325 | macOS 10.14 Mojave (2018) | 174 | | `OS_MACOS_CATALINA` | 326 | macOS 10.15 Catalina (2019) | 175 | | `OS_MACOS_BIGSUR` | 327 | macOS 11 Big Sur (2020) | 176 | | `OS_MACOS_MONTEREY` | 328 | macOS 12 Monterey (2021) | 177 | | `OS_MACOS_VENTURA` | 329 | macOS 13 Ventura (2022) | 178 | | `OS_MACOS_SONOMA` | 330 | macOS 14 Sonoma (2023) | 179 | | `OS_MACOS_SEQUOIA` | 331 | macOS 15 Sequoia (2024) | 180 | | `OS_MACOS_TAHOE` | 332 | macOS 26 Tahoe (2025) | 181 | 182 | ##### 其他Apple操作系统 183 | 184 | | 宏名称 | 值 | 描述 | 185 | |--------|-----|------| 186 | | `OS_IOS` | 350 | iOS (iPhone/iPod touch) | 187 | | `OS_IPADOS` | 351 | iPadOS (iPad) | 188 | | `OS_WATCHOS` | 352 | watchOS (Apple Watch) | 189 | | `OS_TVOS` | 353 | tvOS (Apple TV) | 190 | | `OS_VISIONOS` | 354 | visionOS (Apple Vision Pro) | 191 | | `OS_BRIDGEOS` | 355 | bridgeOS (Apple T2芯片) | 192 | | `OS_AUDIOOS` | 356 | audioOS (HomePod) | 193 | 194 | ##### BSD系列 195 | 196 | | 宏名称 | 值 | 描述 | 197 | |--------|-----|------| 198 | | `OS_BSD` | 400 | 通用BSD标识 | 199 | | `OS_FREEBSD` | 404 | FreeBSD | 200 | 201 | ##### Unix系列 202 | 203 | | 宏名称 | 值 | 描述 | 204 | |--------|-----|------| 205 | | `OS_UNIX` | 500 | 通用Unix标识 | 206 | 207 | ##### 新兴操作系统 208 | 209 | | 宏名称 | 值 | 描述 | 210 | |--------|-----|------| 211 | | `OS_FUCHSIA` | 950 | Google Fuchsia | 212 | | `OS_HARMONY` | 952 | Harmony OS | 213 | 214 | ##### 其他操作系统 215 | 216 | | 宏名称 | 值 | 描述 | 217 | |--------|-----|------| 218 | | `OS_REACTOS` | 704 | ReactOS | 219 | 220 | ##### 未知操作系统 221 | 222 | | 宏名称 | 值 | 描述 | 223 | |--------|-----|------| 224 | | `OS_UNKNOWN` | 0 | 无法识别的操作系统 | 225 | 226 | ## 命名空间 tc 227 | 228 | ### 输出函数 229 | 230 | #### 标准输出函数 231 | 232 | | 函数 | 描述 | 233 | |------|------| 234 | | `print()` | 无参数打印 | 235 | | `println()` | 无参数打印并换行 | 236 | | `print(Args&&... args)` | 多参数打印 | 237 | | `println(Args&&... args)` | 多参数打印并换行 | 238 | | `tout` | 全局输出对象 (TOut类型) | 239 | 240 | #### 颜色函数 241 | 242 | | 函数 | 描述 | 243 | |------|------| 244 | | `colorize(const std::string& text, ColorController::Color color)` | 返回带指定颜色的字符串 | 245 | | `red(const std::string& text)` | 返回带红色的字符串 | 246 | | `green(const std::string& text)` | 返回带绿色的字符串 | 247 | | `blue(const std::string& text)` | 返回带蓝色的字符串 | 248 | | `yellow(const std::string& text)` | 返回带黄色的字符串 | 249 | 250 | ### 延时函数 251 | 252 | | 函数 | 描述 | 253 | |------|------| 254 | | `wait(double seconds)` | 等待指定秒数(支持小数) | 255 | | `tsleep(int milliseconds)` | 等待指定毫秒,返回TSleep对象 | 256 | | `tsleep_stream` | 延时流对象 (TSleepStream类型) | 257 | 258 | ### 按键等待函数 259 | 260 | | 函数 | 描述 | 261 | |------|------| 262 | | `waitKey()` | 等待任意按键 | 263 | | `waitKey(char key)` | 等待特定字符按键 | 264 | | `waitKey(int key)` | 等待特定键码按键 | 265 | 266 | ### 系统相关函数 267 | 268 | | 函数 | 描述 | 参数 | 返回值 | 269 | |------|------|------|--------| 270 | | `getSystemTime(int type = SYS_TIMESTAMP)` | 获取系统时间 | `type`: 时间类型常量 | 请求的时间值 | 271 | | `systemConsole(const char* cmd)` | 执行系统命令(C字符串版本) | `cmd`: 要执行的命令 | 命令的退出状态 | 272 | | `systemConsole(const std::string& cmd)` | 执行系统命令(C++字符串版本) | `cmd`: 要执行的命令 | 命令的退出状态 | 273 | | `systemConsoleW(const wchar_t* cmd)` | 执行系统命令(宽字符版本,仅Windows平台可用) | `cmd`: 要执行的宽字符命令 | 命令的退出状态 | 274 | | `systemCheck()` | 检测当前操作系统类型 | 无 | 操作系统类型代码 | 275 | | `getOSName(int osCode)` | 获取操作系统名称 | `osCode`: 操作系统代码 | 操作系统名称字符串 | 276 | | `getOSVersionInfo()` | 获取当前操作系统的详细版本信息 | 无 | 操作系统版本信息字符串 | 277 | 278 | ### 终端控制函数 279 | 280 | #### 基本终端控制 281 | 282 | | 函数 | 描述 | 参数 | 返回值 | 283 | |------|------|------|--------| 284 | | `terminal::clear()` | 清屏 | 无 | 无 | 285 | | `terminal::moveCursor(int x, int y)` | 移动光标到指定位置 | `x`: 列坐标, `y`: 行坐标 | 无 | 286 | | `terminal::getSize()` | 获取终端尺寸 | 无 | 包含宽度和高度的对组 | 287 | | `printer()` | 创建Printer对象 | 无 | Printer对象 | 288 | 289 | #### 缓冲区控制 290 | 291 | | 函数 | 描述 | 参数 | 返回值 | 292 | |------|------|------|--------| 293 | | `terminal::flush()` | 刷新终端输出缓冲区 | 无 | 无 | 294 | | `Printer::flush()` | 刷新打印器的输出缓冲区 | 无 | Printer引用 | 295 | 296 | 缓冲区控制函数用于确保终端输出的即时性,特别适用于以下场景: 297 | 298 | - 动画效果显示 299 | - 实时更新的界面 300 | - 进度条显示 301 | - 需要立即显示的状态信息 302 | 303 | 使用示例: 304 | ```cpp 305 | // 使用全局刷新函数 306 | tc::print("\r加载中..."); 307 | tc::terminal::flush(); 308 | 309 | // 使用打印器的刷新方法 310 | tc::printer().print("\r加载中...").flush(); 311 | ``` 312 | 313 | 注意事项: 314 | 1. `print` 函数在检测到 `\r` 字符时会自动调用 `flush` 315 | 2. `println` 函数会自动刷新输出 316 | 3. 在动画效果中,建议每帧后都调用 `flush` 317 | 318 | ## 类参考 319 | 320 | ### PrintProxy 类 321 | 322 | 用于链式打印操作的代理类。 323 | 324 | | 方法 | 描述 | 参数 | 返回值 | 325 | |------|------|------|--------| 326 | | `print()` | 无参数打印 | 无 | PrintProxy引用 | 327 | | `print(Args&&... args)` | 多参数打印 | 任意类型参数 | PrintProxy引用 | 328 | | `println(Args&&... args)` | 多参数打印并换行 | 任意类型参数 | PrintProxy引用 | 329 | 330 | ### Printer 类 331 | 332 | 提供终端控制功能的类。 333 | 334 | | 方法 | 描述 | 参数 | 返回值 | 335 | |------|------|------|--------| 336 | | `clear()` | 清屏 | 无 | Printer引用 | 337 | | `moveCursor(int x, int y)` | 移动光标到指定位置 | `x`: 列坐标, `y`: 行坐标 | Printer引用 | 338 | | `print()` | 无参数打印 | 无 | Printer引用 | 339 | | `print(Args&&... args)` | 多参数打印 | 任意类型参数 | Printer引用 | 340 | | `println(Args&&... args)` | 多参数打印并换行 | 任意类型参数 | Printer引用 | 341 | | `hideCursor()` | 隐藏光标 | 无 | Printer引用 | 342 | | `showCursor()` | 显示光标 | 无 | Printer引用 | 343 | | `moveCursor(Direction dir, int n)` | 按方向移动光标 | `dir`: 方向, `n`: 移动距离 | Printer引用 | 344 | | `getSize()` | 获取终端尺寸 | 无 | 包含宽度和高度的对组 | 345 | 346 | ### ColorController 类 347 | 348 | 控制终端颜色的静态类。 349 | 350 | | 方法 | 描述 | 参数 | 返回值 | 351 | |------|------|------|--------| 352 | | `setColor(Color color)` | 设置颜色 | `color`: 颜色枚举值 | 无 | 353 | | `setRGBColor(int r, int g, int b)` | 设置RGB颜色 | `r,g,b`: RGB颜色值(0-255) | 无 | 354 | | `setBold(bool enable)` | 设置粗体 | `enable`: 是否启用 | 无 | 355 | 356 | ### ColorWrapper 类 357 | 358 | 用于流式输出颜色的包装器类。 359 | 360 | | 方法 | 描述 | 参数 | 返回值 | 361 | |------|------|------|--------| 362 | | `ColorWrapper(ColorController::Color color)` | 构造函数 | `color`: 颜色枚举值 | 无 | 363 | | `operator<<` | 输出运算符重载 | `os`: 输出流, `wrapper`: 颜色包装器 | 输出流引用 | 364 | 365 | ### RGBColorWrapper 类 366 | 367 | 用于流式输出RGB颜色的包装器类。 368 | 369 | | 方法 | 描述 | 参数 | 返回值 | 370 | |------|------|------|--------| 371 | | `RGBColorWrapper(int r, int g, int b)` | 构造函数 | `r,g,b`: RGB颜色值(0-255) | 无 | 372 | | `operator<<` | 输出运算符重载 | `os`: 输出流, `wrapper`: RGB颜色包装器 | 输出流引用 | 373 | 374 | ### FontStyleWrapper 类 375 | 376 | 用于流式输出字体样式的包装器类。 377 | 378 | | 方法 | 描述 | 参数 | 返回值 | 379 | |------|------|------|--------| 380 | | `FontStyleWrapper(bool enable)` | 构造函数 | `enable`: 是否启用 | 无 | 381 | | `operator<<` | 输出运算符重载 | `os`: 输出流, `wrapper`: 字体样式包装器 | 输出流引用 | 382 | 383 | ### TSleep 类 384 | 385 | 用于延时操作的类。 386 | 387 | | 方法 | 描述 | 参数 | 返回值 | 388 | |------|------|------|--------| 389 | | `TSleep(int ms)` | 构造函数 | `ms`: 毫秒数 | 无 | 390 | | `execute()` | 执行延时 | 无 | 无 | 391 | | `operator<<` | 输出运算符重载 | `os`: 输出流, `sleep`: 延时对象 | 输出流引用 | 392 | 393 | ### TSleepStream 类 394 | 395 | 用于流式延时的类。 396 | 397 | | 方法 | 描述 | 参数 | 返回值 | 398 | |------|------|------|--------| 399 | | `operator<<(int milliseconds)` | 延时操作符 | `milliseconds`: 毫秒数 | 无 | 400 | 401 | ### ProgressBar 类 402 | 403 | 进度条类。 404 | 405 | | 方法 | 描述 | 参数 | 返回值 | 406 | |------|------|------|--------| 407 | | `ProgressBar(int width, std::string done = "#", std::string todo = "-", std::string color = TCOLOR_GREEN)` | 构造函数 | `width`: 宽度, `done`: 已完成字符, `todo`: 未完成字符, `color`: 颜色 | 无 | 408 | | `show(double progress, const std::string& msg = "Loading...")` | 显示进度 | `progress`: 进度值(0.0-1.0), `msg`: 消息 | 无 | 409 | | `finish(std::string content = "Finished")` | 完成进度条 | `content`: 完成消息 | 无 | 410 | 411 | ### TOut 类 412 | 413 | 自定义输出流类,支持链式输出和自定义类型。 414 | 415 | | 方法 | 描述 | 参数 | 返回值 | 416 | |------|------|------|--------| 417 | | `TOut(std::ostream& os = std::cout)` | 构造函数 | `os`: 输出流 | 无 | 418 | | `operator<<(T&& value)` | 通用输出操作符 | `value`: 要输出的值 | TOut引用 | 419 | | `operator<<(const TSleep& sleep)` | 特化处理TSleep | `sleep`: 延时对象 | TOut引用 | 420 | | `operator<<(const ColorWrapper& color)` | 特化处理颜色包装器 | `color`: 颜色包装器 | TOut引用 | 421 | | `operator<<(const RGBColorWrapper& color)` | 特化处理RGB颜色包装器 | `color`: RGB颜色包装器 | TOut引用 | 422 | | `operator<<(const FontStyleWrapper& style)` | 特化处理字体样式包装器 | `style`: 字体样式包装器 | TOut引用 | 423 | | `operator<<(std::ostream& (*manip)(std::ostream&))` | 支持标准流操作符 | `manip`: 流操作符 | TOut引用 | 424 | | `stream()` | 获取底层流 | 无 | 输出流引用 | 425 | 426 | ### Win32Console 类 427 | 428 | Windows平台下的控制台管理类。 429 | 430 | | 方法 | 描述 | 参数 | 返回值 | 431 | |------|------|------|--------| 432 | | `getInstance()` | 获取单例实例 | 无 | Win32Console引用 | 433 | | `isInitialized()` | 判断是否初始化 | 无 | 布尔值 | 434 | | `setColor(WORD color)` | 设置颜色 | `color`: 颜色值 | 无 | 435 | | `pushColor(WORD color)` | 推入当前颜色到栈 | `color`: 颜色值 | 无 | 436 | | `popColor()` | 弹出颜色栈并恢复 | 无 | 无 | 437 | | `resetColor()` | 重置为原始颜色 | 无 | 无 | 438 | | `getCurrentColor()` | 获取当前颜色 | 无 | 颜色值 | 439 | | `moveCursor(int x, int y)` | 移动光标 | `x`: 列坐标, `y`: 行坐标 | 无 | 440 | | `clearScreen()` | 清屏 | 无 | 无 | 441 | | `getConsoleSize()` | 获取终端尺寸 | 无 | 包含宽度和高度的对组 | 442 | | `rgbToWin32Color(int r, int g, int b)` | RGB转16色近似 | `r,g,b`: RGB颜色值(0-255) | 颜色值 | 443 | 444 | ## 使用示例 445 | 446 | ### 基本输出 447 | 448 | ```cpp 449 | // 标准输出 450 | tc::print("Hello", " ", "World"); 451 | tc::println("Hello", " ", "World"); 452 | 453 | // 流式输出 454 | tc::tout << "Hello World" << std::endl; 455 | 456 | // 带颜色的输出 457 | tc::println(TCOLOR_RED, "红色文本", TCOLOR_RESET); 458 | tc::tout << TCOLOR_BLUE << "蓝色文本" << TCOLOR_RESET << std::endl; 459 | ``` 460 | 461 | ### 延时操作 462 | 463 | ```cpp 464 | // 等待1.5秒 465 | tc::wait(1.5); 466 | 467 | // 等待1000毫秒 468 | tc::tsleep(1000).execute(); 469 | 470 | // 流式延时 471 | tc::tout << "等待前" << tc::tsleep(500) << "等待后" << std::endl; 472 | 473 | // 延时流 474 | tc::tsleep_stream << 1000; 475 | ``` 476 | 477 | ### 按键等待 478 | 479 | ```cpp 480 | // 等待任意按键 481 | tc::waitKey(); 482 | 483 | // 等待特定按键 484 | tc::waitKey('A'); 485 | tc::waitKey(KEY_ESC); 486 | ``` 487 | 488 | ### 终端控制 489 | 490 | ```cpp 491 | // 清屏 492 | tc::printer().clear(); 493 | 494 | // 移动光标 495 | tc::printer().moveCursor(10, 5); 496 | 497 | // 隐藏/显示光标 498 | tc::printer().hideCursor(); 499 | tc::printer().showCursor(); 500 | 501 | // 获取终端尺寸 502 | auto size = tc::printer().getSize(); 503 | ``` 504 | 505 | ### 进度条 506 | 507 | ```cpp 508 | // 创建进度条 509 | tc::ProgressBar bar(30, "█", "░", TCOLOR_GREEN); 510 | 511 | // 显示进度 512 | for (int i = 0; i <= 100; ++i) { 513 | bar.show(i / 100.0, "处理中..."); 514 | tc::wait(0.02); 515 | } 516 | 517 | // 完成进度条 518 | bar.finish("完成!"); 519 | ``` 520 | 521 | ### 系统相关 522 | 523 | ```cpp 524 | // 获取系统时间 525 | int year = tc::getSystemTime(SYS_YEAR); 526 | int timestamp = tc::getSystemTime(); 527 | 528 | // 执行系统命令 529 | tc::systemConsole("echo Hello World"); 530 | 531 | // 执行Unicode命令(Windows平台) 532 | #ifdef _WIN32 533 | tc::systemConsoleW(L"echo 你好世界"); 534 | #endif 535 | 536 | // 检测系统类型 537 | int os = tc::systemCheck(); 538 | const char* osName = tc::getOSName(os); 539 | std::string osVersionInfo = tc::getOSVersionInfo(); 540 | 541 | // 显示系统信息 542 | tc::println("当前系统: ", osName); 543 | tc::println("系统版本: ", osVersionInfo); 544 | ``` 545 | 546 | --- 547 | 548 | 本文档提供了 TC.hpp 库的完整 API 参考。更多详细信息和高级用法,请参考源代码中的注释和示例。 549 | --------------------------------------------------------------------------------