一 什么是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);
/* 33[1K代表清行,33[16D代表光標左移16字符。 */
printf("\033[1K\033[16D"); ///< 光標回到行首
}
}
int main(void)
{
progressbar(1);
}
實現效果
參考文獻
[1] ANSI escape code (http://en.volupedia.org/wiki/ANSI_escape_code)