C
在 C 中使用 ANSI 转义码
C 没有 ESC 的转义字面量 —— 请写 \x1b(十六进制)或 \033(八进制)。printf 与 fputs 在所有平台均按字节透传;在 Windows 10+ 上需先用 SetConsoleMode(..., ENABLE_VIRTUAL_TERMINAL_PROCESSING) 启用虚拟终端处理。任何接近 TUI 的需求(菜单、窗口、鼠标)请直接链接 ncurses,不要自行实现。
推荐库
- ncurses
C 的标准 TUI 库 —— 窗口、面板、菜单、表单、配色对。处理 terminfo 查找与原始输入,让你无需直接发送 ANSI。
- termios
POSIX 终端属性 API(
<termios.h>)—— 切换到原始模式、关闭回显、关闭 ICANON 以读取单个按键。读取终端回送的鼠标 / 焦点 / 括号粘贴转义时必备。 - termcap / terminfo (term.h)
setupterm()+tigetstr()查询能力(如setaf、cup、civis),返回当前$TERM对应的转义字符串。 - notcurses
ncurses 的现代继任者 —— TrueColor、sixel/Kitty 图形、Unicode 感知。需要超出 ncurses 能力的新代码可选。
常用写法
#include <stdio.h>
int main(void) {
printf("\x1b[1;31merror:\x1b[0m permission denied\n");
return 0;
}#include <stdio.h>
#include <term.h>
#include <stdlib.h>
int main(void) {
setupterm(NULL, 1, NULL);
char *red = tigetstr("setaf"); // takes one parameter
char *reset = tigetstr("sgr0");
putp(tparm(red, 1));
fputs("error: permission denied", stdout);
putp(reset);
putchar('\n');
return 0;
}
/* link with: cc prog.c -lncurses */#include <stdio.h>
#include <signal.h>
#include <unistd.h>
static void restore(int sig) { (void)sig; printf("\x1b[?25h"); _exit(0); }
int main(void) {
signal(SIGINT, restore);
signal(SIGTERM, restore);
printf("\x1b[?25l"); // hide cursor
for (int i = 0; i <= 100; i++) {
printf("\r\x1b[K%d%%", i);
fflush(stdout);
usleep(20000);
}
printf("\n");
printf("\x1b[?25h"); // show cursor
return 0;
}#include <termios.h>
#include <unistd.h>
#include <stdio.h>
int main(void) {
struct termios orig, raw;
tcgetattr(STDIN_FILENO, &orig);
raw = orig;
raw.c_lflag &= ~(ICANON | ECHO); // no line-buffering, no echo
tcsetattr(STDIN_FILENO, TCSANOW, &raw);
/* now reads of stdin deliver single bytes including ESC sequences */
int c;
while ((c = getchar()) != 'q') { printf("0x%02x ", c); fflush(stdout); }
tcsetattr(STDIN_FILENO, TCSANOW, &orig); // always restore
return 0;
}