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;
}