如果您的终端(或者更可能是终端仿真器)支持 VT100 样式的转义序列,您可以打印特定的代码序列来控制光标位置、清除部分或全部屏幕/窗口等。
例如,要将光标向上移动 1 行:
printf("\x1b[A");
fflush(stdout);
要将光标向上移动 2 行,请执行两次或:
printf("\x1b[2A"});
fflush(stdout);
这些通常称为ANSI 转义码;该链接指向列出其中许多的 Wikipedia 文章。它们首先由旧的 DEC VT-100 终端实现,大多数现代终端和仿真器都对其进行了仿真。
还有这个:
printf("\x1b[J");
fflush(stdout);
将清除部分屏幕,从当前光标位置到底部。
这些序列应该足以满足您的需求。(它们可能无法在 Windows 命令窗口中工作。)
更便携,如果您的系统支持它,您可以使用termcap
或terminfo
确定当前终端的正确命令序列(由$TERM
环境变量确定)。该tput
命令允许您在命令行上执行此操作;man tput
了解更多信息。实际上,您现在不太可能找到一个支持 termcap 或 terminfo 的系统,其终端与 VT100 不兼容;打印原始转义序列严格来说是不可移植的,但可能已经足够好了。
一个建议:您的程序可能应该有一个选项来禁止任何此类控制序列;例如,如果想要将输出重定向到文件的用户不希望在文件中包含这些转义序列。有些程序只有在可以确定 stdout 是终端时才使用控制序列,但显式选项也是一个好主意。
*更新:*
这是我编写的一个程序,它演示了如何使用terminfo
. 它应该适用于几乎任何类 Unix 系统。
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <term.h>
#include <unistd.h>
int main(void) {
const char *term = getenv("TERM");
if (term == NULL) {
fprintf(stderr, "TERM environment variable is not set\n");
exit(EXIT_FAILURE);
}
setterm(term);
for (int i = 0; i < 10; i ++) {
putp(tparm(clr_eos));
printf("%d\n%d\n", i, i+1);
sleep(1);
putp(tparm(parm_up_cursor, 2));
}
return 0;
}