【问题标题】:How is erasing output in terminal implemented in C?如何在 C 中实现终端中的擦除输出?
【发布时间】:2014-11-08 06:37:20
【问题描述】:

在终端中运行的某些应用程序可以擦除它们的输出。例如 当它告诉你等待时,它会显示一系列在不同长度之间交替的点。

如何在 C 中实现终端中的擦除输出?是通过反向换行完成的吗?

程序能否只擦除当前行中的前一个字符,而不是 stdout 中上一行中的字符?

谢谢。

【问题讨论】:

  • 好吧,C 不懂屏幕的概念。所以任何代码都不能移植。根据您的需要,也许看看 conio.h 或 curses?我复制自:stackoverflow.com/questions/2347770/…
  • 我认为您正在寻找以下内容。 stackoverflow.com/questions/2208126/… 以下是您要查找的代码。 stackoverflow.com/questions/1348563/…
  • 嗯,这取决于终端类型。某些类型可以执行“破坏性”退格,其他类型需要执行 cursor-left+delete char,或者甚至 CR+ 重写整行。查看 termcap/terminfo 了解更多详情...
  • 擦除当前行通常使用回车\r字符。

标签: c


【解决方案1】:

这取决于终端。

Windows 上的 COMSPEC shell(通常称为 DOS 提示符或 command.com)在 C 中公开了一个 API 来控制光标。我没有做过任何 Windows 编程,所以我不能告诉你太多。

大多数其他终端(尤其是在 unixen 上)模拟类似于 VT100 串行终端的协议(VT100 终端是一种物理设备、监视器和键盘,您连接到调制解调器或串行端口以与服务器通信)。

在 VT100 终端上,回车和换行是单独的命令,都是一个字节。回车命令将光标设置到行首。换行命令将光标向下移动一行(但不会将光标单独带到行首)。 unixen 上的大多数 shell 会在换行后自动插入回车,但几乎没有一个会在回车后插入换行。

有了这些知识,最简单的实现就是简单地输出一个回车并重新打印整行:

printf("\rprogress: %d percent  ", x);

注意行尾的多余空格。打印"\r" 不会删除该行,因此在旧行上重新打印可能最终会在屏幕上留下一些旧字符串。多余的空格用于尝试删除旧行的剩余部分。

如果您在 Google 上搜索 "VT100 escape secquence",您会发现一些命令可以让您执行诸如擦除当前行、更改文本颜色、转到屏幕上的特定行/列等操作。VT100 序列的最流行用途是输出彩色文本。但你也可以用它们做其他事情。

下一个最简单的实现是干净地删除该行并重新打印它:

printf("\033[2K\rprogress: %d percent", x);

\033[2K 是删除当前行的转义序列 (ESC[2K)。

如果您愿意,您可以从这里获得更多创意。您可以将光标保存/恢复命令与擦除直到行尾命令一起使用,以仅擦除要更新的部分(而不是整行)。您可以使用 goto 命令将光标放在屏幕上的特定位置以更新那里的文本等。

应该注意的是,更高级的东西,例如 VT102 序列或一些完整的 ANSI 转义序列通常不是跨终端的可移植(终端我不是指 shell,我指的是终端:rxvt、xterm、 linux终端,超级终端(在windows上)等)。

如果您想要可移植性(和/或健全的 API),您应该使用 curses 或 ncurses 库。

如果您想知道它是如何完成的,那就是它的完成方式。它只是将特殊格式的字符串打印到屏幕上(COMSPEC shell 除外)。有点像 HTML,但有点老派。

【讨论】:

  • 应该注意,这些都不是 C 特定的。如果需要,您可以在 shell 脚本或任何脚本语言(甚至是 makefile)中执行此操作。这是了解 VT100 命令的真正价值——当你不能使用 curses 或 ncurses 时。
猜你喜欢
  • 2011-01-13
  • 2020-11-29
  • 2013-06-05
  • 2022-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-23
相关资源
最近更新 更多