在不打印控制字符的情况下用C清除屏幕

时间:2020-10-27 20:14:05

标签: c linux

这里的C总数。使用Linux。我只是想在C程序中清除屏幕。我已经尝试过找到的每种方法,但是每一种方法,我都会得到控制序列(我认为这就是所谓的)^ [[3J ^ [[H ^ [[2J开头打印。程序输出到屏幕。那时我看不到它们,但是当我将输出重定向到文件然后查看文件时,它们就在那里。有帮助吗?

1 个答案:

答案 0 :(得分:0)

实际序列为"\033[3J\033[H\033[2J",其中包含三个ANSI escape codes

  • "\033[3J" = CSI 3 J:清除终端屏幕并删除回滚缓冲区中的所有内容。特定于xterm终端。

  • "\033[H" = CSI H:将光标移到左上角。

  • "\033[2J" = CSI 2 J:清除终端屏幕。

尽管这些序列适用于大多数(如果不是全部)当前终端仿真器,但是生成的实际代码来自POSIX terminal interface数据库中的当前终端。因此,对序列进行硬编码不是一个好主意,而是使用终端接口。

要使用终端界面,请使用ncurses。您可以使用C库界面或命令行实用程序(clearreset,后者可以将终端属性重置为正常/默认值,以防先前的程序使它们杂乱无章或无法使用的状态。

不想使用终端界面,但想清除终端是一个奇怪的组合;在Unix或POSIX环境中是非典型的。您应该重新考虑为什么要这样做。例如,如果仅仅是因为您发现读取输出更容易,则可以通过less传递输出,或改为运行clear ; ./yourprog

在二十多年前的MS-DOS时代,成语system("cls");很普遍。这执行了MS-DOS命令cls,该命令清除了屏幕。 (如果加载了ANSI.SYS,那么上面提到的ANSI转义序列也可以正常工作。)

在Unix和POSIXy系统中,可以使用isatty()函数来测试文件描述符是否指向终端。为了获得最大的兼容性,可以将宏STDIN_FILENOSTDOUT_FILENOSTDERR_FILENO用于三个标准文件描述符,尽管在Linux中它们始终分别为0、1和2。

因此,从技术上讲,您可以使用

if (isatty(1))
    system("clear     2>/dev/null");
else
if (isatty(2))
    system("clear >&2 2>/dev/null");

检查标准输出或标准错误是否是终端,如果是终端,请使用ncurses clear命令行命令清除它。根据POSIX.1,system()使用POSIX Shell。上面的命令使用POSIX Shell重定向来确保命令的输出到达所需的描述符,并且将来自Shell或命令的任何错误消息(例如,如果不存在)重定向到空设备,即将其丢弃。因此,如果将标准输出和标准错误都重定向到文件或设备或非终端的任何内容,则不会输出任何内容。它不会向重定向输出发出ANSI转义代码。

还是,您应该重新考虑。将此类功能烘焙到简单的命令行命令中是非典型的。而且,在执行实际命令之前,先制作要清除的shell别名或包装脚本很简单,因此无需将其烘烤。