一 什么是ANSI控制码(ANSI escape sequences)
维基百科给出的解释如下:
ANSI escape sequences are a standard for in-band signaling to control cursor location, color, font styling, and other options on video text terminals and terminal emulators. Certain sequences of bytes, most starting with an ASCII escape character and a bracket character, are embedded into text. The terminal interprets these sequences as commands, rather than text to display verbatim.
标准控制码是一个标准用于规范控制视频文本终端和模拟终端上的光标位置,颜色,字体样式和其他选项的带内信号(笔者注:用于规范带内信号)。这些特定的序列,大都以一个ASCII的 'escape' 字符和一个 '[' 字符开头,并被嵌入到文本中,终端将这些特定的序列解释成命令,而不是显示在屏幕上的文本。
二 CSI (Control Sequence Introducer) sequences
ANSI标准规定 'esc' 字符后面所跟的第一个字符用于标识序列的类型,同时又根据第一个字符的大小将Escape序列分为四个大类:
- nF Escape Sequence (0x20~0x2F),
- Fp Escape Sequence (0x30~0x3F),例如:esc [
- Fe Escape Sequence (0x40~0x5F),例如:esc 7
- Fs Escape Sequence (0x60~0x7E),例如:esc c
为了不偏离本文的中心,我们这里只关注当 'esc' 后面接 '[' 的情况,当 'esc'后面接 '[' 时我们称之为CSI序列。下面给出几个常用的CSI序列语法(格式中CSI指代esc [)。
格式 | 说明 |
CSI n A | 光标上移n行 |
CSI n B | 光标下移n行 |
CSI n C | 光标往前移动n字符 |
CSI n D | 光标往后移动n字符 |
CSI n J | 清屏 |
CSI n K | 清行(n取0时,清空光标到行尾的所有字符;当n取1时,清空光标到行尾的所有字符;当n取2时,清空整行的字符,光标位置不变。) |
CSI ? 25 h | 显示光标 |
CSI ? 25 I | 隐藏光标 |
三 简单案例
案例:实现进度条效果,每秒增长10%
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define BAR_SIZE 10
void progressbar(int sec)
{
char bar[BAR_SIZE+1] = {0}; /* '\\0' */
for(int j = 1; j <= BAR_SIZE; j++) {
memset(bar, ' ', BAR_SIZE);
memset(bar, '>', j);
printf("[%s]%3d%%", bar, j*10);
fflush(stdout);
sleep(sec);
/* \033[1K代表清行,\033[16D代表光标左移16字符。 */
printf("\\033[1K\\033[16D"); ///< 光标回到行首
}
}
int main(void)
{
progressbar(1);
}
参考文献
[1] ANSI escape code (http://en.volupedia.org/wiki/ANSI_escape_code)