如何使用C/C++刷新在终端上已经打印的内容

写本文的起源是因为在安装一些工具的时候,发现在终端上并行安装的情况下,显示安装信息是会修改之前已经打印出来的内容,这是怎么做到的呢?抱着对这个问题的好奇我进行了一些探索。

终端是如何运行的

首先是最关键的问题:终端是如何运行的?

这个问题并不是我思考的第一个问题,但是在写本文的时候,我认为这是最关键的问题,思考了这个文件,那么面对一些问题就很好解释了:

下面介绍一下标准输出(stdout)和 C/C++ 之间的工作流程:

第一,标准输出(stdout)是一个只读文件,并不能进行修改,终端将会显示这些内容。
第二,如果是 C 语言,那么printf()将内容输出到标准输出(stdout)中,然后终端将会显示这些内容。
第三,如果是 C++,那么cout将会输出内容到缓冲streambuf中,最后在合适的机会将其传递给标准输出stdout中打印出来,比如说遇到fflush()刷新或者\n换行符的时候。

可能你对上面的一些点还是很迷惑,下面仔细来说说看。

刷新单行内容的最佳方法

如果是单行刷新,可以使用转义字符\r\b:前者将会跳转到这行的开头再打印,而后者会移到前一个字符的位置再打印(带入一下旧式的打字机就可以理解了)。

举个例子,在同一行里,从1循环到100,既可以使用\b\b\b(因为最大是三位数):

#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[]) {int i = 1;while (i<=100) {printf("%d\b\b\b", i++);//休眠一秒再进入下次循环,不然显示太快了sleep(1);}return 0;
}

比较推荐使用\r,这样就可以应对不同长度的数字。

但是二者在stdout中的内容并不会被覆盖,而是如下情况:

1\r2\r3\r4\r.......

所以如果需要刷新多行内容这种方法就不行了。因为\r\b本质上并不是删除了之前的内容,而是在这里跳转了光标进行重新渲染输出,标准输出中的内容并没有发生任何改变。而且二者的跳转都是横向跳转的,\n是纵向的变化。

那么多行刷新应该怎么办呢?

多行内容刷新的解决方案一:使用 ANSI Code

这是一个诞生于上世纪七十年代的产物,它被用于控制终端上光标的位置、颜色、字体等属性。ANSI Code 本质是一个 ASCII Code 的组合,也是一种转义字符,结构为\033[XX\033在 ASCII 中就是 “ESC”的意思,转义字符的英文就是 “Escape Character”),并且广泛应用于众多类 Unix 系统的终端中。

如果想打印出下面这样的情况(只刷新第一行的数字):

39
倒计时中

那么就可以使用下面的代码(注意还是使用了\r,因为当前光标上移可能是在中间或最后的位置):

#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[]) {int i = 1;while (i<=100) {printf("%d\n", i++);printf("倒计时中\033[A\r");sleep(1);}return 0;
}

此外个人建议如果使用这种方法,最好在循环外加上printf("\n");,不然结束程序也可能会影响显示。

这里有篇文章记录了各种移动光标的转义字符,可以当做手册查看:《Bash Prompt HOWTO: Chapter 6. ANSI Escape Sequences: Colours and Cursor Movement》

你如果和我一样遍历过/bin,那么你可能会发现知道ls列出的第一个程序就是[(又名test),也是确定“condition”的。不过这个是评估条件的,而不是位置的(这句话是一个小双关),和 ANSI Code 并没有任何关系,只是巧合。

多行内容刷新的解决方案二:使用ncurses或Windows Console API

这种方法需要使用其他的库,根据平台选择 ncurses(类 Unix)或Windows Console API(Windows)。

个人不是很推荐这种方法:

  • 第一,不是自带的,有些终端不能用;
  • 第二,编译构建安装的时间有点长;
  • 第三,这种方法类似less会新建一个窗口或者清空窗口进行显示。这种方法的样式不是我需要的。

不过作为技术储备,我还是进行了一些研究。

ncurses 的下载地址为https://invisible-island.net/ncurses/#download_ncurses。

下载之后,解压配置安装的命令如下:

$ tar zxvf ncurses-xxx.tar.gz
$ cd ncurses-xxx
$ ./configure
$ make -j4 
$ sudo make install 

安装好了之后,编译的时候使用-lncurses连接库即可。下面是官方的一个案例,这里假设这个文件为hello.c

#include <ncurses.h>int main()
{	initscr();			/* Start curses mode 		  */printw("Hello World !!!");	/* Print Hello World		  */refresh();			/* Print it on to the real screen */getch();			/* Wait for user input */endwin();			/* End curses mode		  */return 0;
}

编译命令为:

$ cc hello.c `-lncurses

然后运行即可看到结果:

请添加图片描述

这里有很详细的官方文档:https://tldp.org/HOWTO/NCURSES-Programming-HOWTO/可以看看。

希望能帮到有需要的人~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/104288.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法通过村第十四关-堆|青铜笔记|堆结构

文章目录 前言堆的概念和特征堆的构成过程插入操作删除操作总结 前言 若执于空&#xff0c;空亦为障。 --彼得马西森《雪豹》 堆结构是一种非常重要的基础数据结构&#xff0c;也是算法的重要内容&#xff0c;很多题目甚至只能通过用堆来进行&#xff0c;所以我们必须明确什么类…

android 与 flutter 之间的通信

文章目录 前言集成 flutter 混合开发android 与 flutter 之间的通信总结 一、前言 因为flutter 具有跨平台的属性&#xff0c;既可以在android上跑&#xff0c;也能在ios 上跑&#xff0c;所以为了节约开发的成本&#xff0c;减少人力&#xff0c;势必就会用到它。然而已有的…

Matlab地理信息绘图—数据诊断

文章目录 数据诊断分析&#xff08;均值方差&#xff09;Matlab代码实现结果展示 数据诊断分析&#xff08;均值方差&#xff09; 均值方差检测是一种简单但有效的异常检测方法&#xff0c;主要基于样本的均值和方差的统计信息。该方法的核心思想是假设正常的样本点应该聚集在…

CNN-generated images are surprisingly easy to spot... for now

CNN-generated images are surprisingly easy to spot… for now----《目前CNN生成的图像非常容易被发现》 背景&#xff1a; 研究者们发现&#xff0c;仅仅对一种由CNN模型生成的图像进行训练的分类器&#xff0c;也可以检测许多其他模型生成的结果。由此提出这样的观点&#…

C语言中的自定义类型详解(结构体 + 枚举 + 联合(共用体))

文章目录 1. 结构体1.1 结构体的声明1.2 结构体成员的访问1.3 匿名结构体1.4 结构体的自引用1.5 结构体内存对齐&#xff08;计算结构体的大小&#xff09;1.6 结构体传参1.6.1 传值传递1.6.2 传址传递&#xff08;使用指针&#xff09; 2. 位段2.1 什么是位段&#xff1f;2.2 …

铅华洗尽,粉黛不施,人工智能AI基于ProPainter技术去除图片以及视频水印(Python3.10)

视频以及图片修复技术是一项具有挑战性的AI视觉任务&#xff0c;它涉及在视频或者图片序列中填补缺失或损坏的区域&#xff0c;同时保持空间和时间的连贯性。该技术在视频补全、对象移除、视频恢复等领域有广泛应用。近年来&#xff0c;两种突出的方案在视频修复中崭露头角&…

miRNA测序数据生信分析——第四讲,未知物种的生信分析实例

miRNA测序数据生信分析——第四讲&#xff0c;未知物种的生信分析实例 miRNA测序数据生信分析——第四讲&#xff0c;未知物种的生信分析实例1. 下载测序数据2. 原始数据质控——软件fastqc3. 注释tRNA和rRNA&#xff0c;使用Rfam数据库——软件blast&#xff0c;Rfam_statisti…

监控系列(六)prometheus监控DMHS操作步骤

一、监控的操作逻辑 给操作系统安装expect命令expect脚本执行dmhs_console脚本执行 cpt / exec 命令用脚本进行过滤字符串过滤dm_export读取脚本与当前日期作比较&#xff0c;然后返回差值 二、安装步骤 1. linux中Expect工具的安装及使用方法 https://blog.csdn.net/wangta…

mybatis拦截器源码分析

mybatis拦截器源码分析 拦截器简介 mybatis Plugins 拦截器由于Mybatis对数据库访问与操作进行了深度的封装,让我们应用开发效率大大提高,但是灵活度很差拦截器的作用:深度定制Mybatis的开发抛出一个需求 :获取Mybatis在开发过程中执行的SQL语句(执行什么操作获取那条SQL语句…

ChatGPT,AIGC 制作按年份选择的动态条形图

在数据分析与可视化中,条形图是用来进行对比分析,在正负条形图中都有哪些好处与优点呢? 正负条形图是一种常用的数据可视化方式,它的优点和好处包括: 1.明确展示:正负条形图可以清晰地显示出数据中的正负差异,使读者能直观地看出数据的变化和趋势。 2.直观比较:正负条…

苹果电脑其他内存怎么清理?

苹果电脑中的应用程序大部分是可以通过将其拖拽至废纸篓并倾倒来卸载的。但是部分程序在卸载后仍有残留文件&#xff0c;比如support文件和pref设置等文件的。小编今天介绍下苹果电脑清理内存怎么清理卸载残留以及好用的清理技巧分享。 一、苹果电脑清理内存怎么清理 苹果电脑…

简单实现一个todoList(上移、下移、置顶、置底)

演示 html部分 <!DOCTYPE html> <html> <head><title>表格示例</title> </head> <body><table border"1"><thead><tr><th>更新时间</th><th>操作</th></tr></thead…

thinkphp5.1 获取缓存cache(‘cache_name‘)特别慢,php 7.0 unserialize 特别慢

thinkphp5.1 获取缓存cache(‘cache_name’)特别慢&#xff0c;php 7.0 unserialize 特别慢 场景&#xff1a; 项目中大量使用了缓存&#xff0c;本地运行非常快&#xff0c;二三百毫秒&#xff0c;部署到服务器后 一个表格请求就七八秒&#xff0c;最初猜想是数据库查询慢&am…

KY258 日期累加

KY258 日期累加 int main() {int n 0; //样例个数cin >> n;//for循环处理n个样例for (int i 0; i < n; i){int y, m, d, num;int days[12] { 31,28,31,30,31,30,31,31,30,31,30,31 };//输入年月日 要加的天数cin >> y >> m >> d >>…

完整教程:Java+Vue+Websocket实现OSS文件上传进度条功能

引言 文件上传是Web应用开发中常见的需求之一&#xff0c;而实时显示文件上传的进度条可以提升用户体验。本教程将介绍如何使用Java后端和Vue前端实现文件上传进度条功能&#xff0c;借助阿里云的OSS服务进行文件上传。 技术栈 后端&#xff1a;Java、Spring Boot 、WebSock…

【Java学习之道】GUI开发的基本概念

引言 在这一章&#xff0c;我们将一起走进Java的图形用户界面&#xff08;GUI&#xff09;开发的世界。在你阅读完这篇文章后&#xff0c;你将能够了解什么是GUI&#xff0c;以及如何使用Java进行GUI的开发。 一、什么是GUI 首先&#xff0c;让我们来解答一个许多初学者都会…

AN基础工具——变形工具

【AN基础工具——变形工具】 基本使用方法&#xff1a;任意变形工具基础动画 本篇内容&#xff1a;学会使用变形工具 重点内容&#xff1a;变形工具 工 具&#xff1a;Adobe Animate 2022 基本使用方法&#xff1a; 任意变形工具 《任意变形工具&#xff08;快捷键Q&#xff0…

深度学习系列51:hugging face加速库optimum

1. 普通模型 Optimum是huggingface transformers库的一个扩展包&#xff0c;用来提升模型在指定硬件上的训练和推理性能。Optimum支持多种硬件&#xff0c;不同硬件下的安卓方式如下&#xff1a; 如果是国内安装的话&#xff0c;记得加上-i https://pypi.tuna.tsinghua.edu.c…

八大排序算法(含时间复杂度、空间复杂度、算法稳定性)

文章目录 八大排序算法(含时间复杂度、空间复杂度、算法稳定性)1、&#xff08;直接&#xff09;插入排序1.1、算法思想1.2、排序过程图解1.3、排序代码 2、希尔排序3、冒泡排序3.1、算法思想3.2、排序过程图解3.3、排序代码 4、&#xff08;简单&#xff09;选择排序4.1、算法…

Springcloud笔记(2)-Eureka服务注册中心

Eureka服务注册 Eureka作为一个微服务的治理中心&#xff0c;它是一个服务应用&#xff0c;可以接收其他服务的注册&#xff0c;也可以发现和治理服务实例。 服务治理中心是微服务&#xff08;分布式&#xff09;架构中最基础和最核心的功能组件&#xff0c;它主要对各个服务…