Windows下用SetConsoleTextAttribute可直接控制文字颜色,需获取控制台句柄并按位组合颜色值,注意重置避免污染后续输出;Linux/macOS则用ANSI转义序列实现跨平台着色。

Windows下用SetConsoleTextAttribute控制文字颜色
在Windows控制台中,最直接、无需第三方依赖的方式是调用WinAPI的SetConsoleTextAttribute。它能实时修改后续输出文字的前景色(文字)和背景色,但不支持ANSI转义序列(除非启用Virtual Terminal Processing且系统版本≥10.0.16275)。实操时注意:必须先获取控制台句柄(GetStdHandle(STD_OUTPUT_HANDLE)),且颜色值是按位组合的——比如FOREGROUND_GREEN | FOREGROUND_INTENSITY表示亮绿色,BACKGROUND_RED单独用会改变背景,混用需小心覆盖。
常见错误是忘记重置颜色,导致后续所有输出都染色。建议封装一个作用域内自动恢复的RAII类,或每次菜单项输出后显式设回默认(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)。
Linux/macOS用ANSI转义序列实现跨平台基础着色
Unix-like系统原生支持ANSI颜色码,例如\033[32m设绿色文字,\033[44m设蓝色背景,\033[0m重置。C++里可直接std::cout 。但要注意:某些旧终端或IDE内置终端(如部分VS Code配置)可能默认禁用ANSI,需确认<code>TERM环境变量有效,或调用setenv("TERM", "xterm-256color", 1)提前声明。
多层级菜单中,不同层级常需视觉区分:一级菜单用加粗+亮色(\033[1;36m),二级用普通色(\033[33m),当前选中项加下划线(\033[4m)。避免嵌套过深导致转义码混乱,推荐把颜色字符串定义为const char*常量,而非硬编码散落各处。
立即学习“C++免费学习笔记(深入)”;
跨平台统一处理:检测平台并桥接颜色逻辑
若程序需同时跑在Windows和Linux/macOS上,别强行统一API,而是用预编译宏分发:Windows走SetConsoleTextAttribute,其他走ANSI。关键点在于——Windows 10 1511+其实也支持ANSI,但默认关闭。可在程序启动时调用SetConsoleMode启用ENABLE_VIRTUAL_TERMINAL_PROCESSING,这样就能统一用ANSI写法,省去平台判断。
实操步骤:
- 调用
GetStdHandle(STD_OUTPUT_HANDLE)获取句柄 - 用
GetConsoleMode读取当前模式 - 用
SetConsoleMode按位或上ENABLE_VIRTUAL_TERMINAL_PROCESSING - 失败则fallback到传统
SetConsoleTextAttribute
这个开关只需执行一次,之后std::cout 在Windows也能生效。
菜单结构与颜色状态管理容易被忽略的细节
颜色本身不难,难的是让多层级菜单的视觉状态(如“当前高亮项”“已展开子菜单”“禁用选项”)与颜色准确绑定。别用全局变量存当前选中索引再if-else刷颜色——容易错乱。更稳妥的做法是把菜单项抽象为结构体,带color_code字段和is_active标志,在渲染循环中统一查表映射:
struct MenuItem {
std::string label;
bool is_enabled = true;
bool is_selected = false;
int level = 0; // 0=顶层, 1=子项...
};
然后写一个get_color_for_item(const MenuItem& item)函数,根据level、is_selected、is_enabled返回对应ANSI串或WinAPI颜色值。这样新增层级或交互逻辑时,颜色逻辑不会散落在各处,也不易漏掉某一种状态的样式。
真正麻烦的是光标定位和清行——如果菜单支持键盘上下导航,移动时得擦除旧高亮、重绘新高亮,否则残留颜色块。别依赖system("cls"),它太重且跨平台不一致;用\033[2K\033[1G(清当前行+回行首)更精准。


















