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

news2024/11/25 0:41:59

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

终端是如何运行的

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

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

下面介绍一下标准输出(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.coloradmin.cn/o/1090850.html

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

相关文章

华为OD机考算法题:基站维修工程师

题目部分 题目基站维护工程师难度难题目说明题目说明小王是一名基站维护工程师&#xff0c;负责某区域的基站维护。 某地方有 n 个基站 ( 1 < n < 10 )&#xff0c;已知各基站之间的距离 s ( 0 < s < 500 )&#xff0c;并目基站 x 到基站 y 的距离&#xff0c;与基…

力扣第669题 修剪二叉搜索树 c++(注释)

题目 669. 修剪二叉搜索树 中等 相关标签 树 深度优先搜索 二叉搜索树 二叉树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元…

实验室超声波清洗机有什么优点?

无论是在工业生产中&#xff0c;还是在日常生活中&#xff0c;清洁工作总是贯穿其中。特别是在社会加工过程中&#xff0c;必须清洗仪器和表面的工作量很大。此外&#xff0c;还有许多人力不能接触到需要清洗的部分&#xff0c;需要使用专业设备进行清洗工作。实验室超声波清洗…

【数值分析】0 - 数值分析绪论

文章目录 一、数值分析介绍二、数值分析应用2.1 解三角函数2.2 计算多项式2.3 解线性方程组2.4 供水计划和生产调度计划的制定2.5 湘江水流量估计的实际意义2.6 机器学习或大数据 三、数值分析内容四、数值分析参考书目 学习视频&#xff1a;《数值分析》| 华科 | 研究生基础课…

C++标准模板(STL)- 类型支持 (数值极限,max_digits10,radix,min_exponent)

数值极限 定义于头文件 <limits> 定义于头文件 <limits> template< class T > class numeric_limits; numeric_limits 类模板提供查询各种算术类型属性的标准化方式&#xff08;例如 int 类型的最大可能值是 std::numeric_limits<int>::max() &…

XXL-Job分布式任务调度框架-单机模式和分片模式执行任务4

一 调度模式分类 1.1 调度模式 1.单个任务&#xff1a;一个任务实例便可完成 a)单机单任务&#xff1a;单机模式下任何路由模式都只有一个实例执行 b)集群单任务&#xff1a;由路由策略(广播模式除外)选择其中一个实例完成 2.集群部署&#xff1a;每个实例都同时执行一部分…

RS232电路设计

学习一下RS232的电路设计 在学习过RS485电路设计后&#xff0c;对232就没那么陌生了。 下面我来说一下对于一个新手从0到1 的过程 首先我会查询关于RS232的相关只是&#xff0c;对他有初步了解&#xff0c;在485的基础上很好理解232了。 串口、COM口、UART口, TTL、RS-232、…

尚硅谷Flink(一)

目录 ☄️前置工作 fenfa脚本 &#x1f30b;概述 ☄️Flink是什么 ☄️特点&#xff08;多nb&#xff09; ☄️应用场景&#xff08;不用看&#xff09; ☄️分层API &#x1f30b;配环境 ☄️wordcount ☄️WcDemoUnboundStreaming &#x1f30b;集群部署 ☄️集…

机器视觉工程师为什么要反复调试?

目录 那么程序debug原因有哪些&#xff1f;图像处理debug的原因有哪些&#xff1f; 我们机器视觉项目的程序包含&#xff0c;业务逻辑图像处理&#xff0c;所以我们不单单调试图像处理部分&#xff0c;还要调试C#&#xff0c;界面&#xff0c;数据等等。我们必须保证程序稳定性…

手把手带你用Python和文心一言搭建《AI看图写诗》网页项目(附上完整项目源码)

今年年初&#xff0c;ChatGPT的火爆在全球掀起AI大模型的开发热潮&#xff0c;国内外的科技公司纷纷加入“百模大战”行列。百度在率先发布了国内第一款人工智能大语言模型“文心一言”后&#xff0c;又推出了文心千帆大模型平台&#xff0c;帮助企业和开发者加速大模型应用落地…

ARRI阿莱MXF(ALEXA Mini LF)多碎片重组案例

三大影视巨头ARRI、RED、ATOMOS&#xff0c;ARRI阿莱的设备以提供电影级的画质而在影视圈有很大的名气。ARRI的文件一般是两种&#xff0c;一种是高清MOV&#xff08;苹果为ARRI专门出过特殊认证的编码&#xff09;&#xff1b;一种是高清MXF&#xff1b;相比之下MXF文件比较少…

Vue之Jwt的运用(一起探索JWT在Vue中的用途吧)

目录 前言 一、JWT简介 1. 什么是JWT 2. JWT的工作原理 3. JWT的组成 4. 使用JWT的好处 二、JWT工具类 JwtFilter JwtUtils 工具类的作用 工具类的测试 测试代码 test01()测试结果 test02()测试结果 test03()测试结果 test04测试结果 test05测试结果 三、JWT集成SPA项…

Arya科普 | 程序员常用英语 Java常用名词解释 计算机常用英语汇总

本篇博客汇总了程序员常用的英文单词&#xff0c;Java中常用的名词解释&#xff0c;计算机常用的英语汇总。 英文 A~D array数组 accessible 可存取的 area面积 audio 音频 addition 加法 action 行动 arithmetic 算法 adjustment 调整 actual 真实的 argument 参量 ascent …

CVE-2017-7529 Nginx越界读取内存漏洞

漏洞概述 当使用Nginx标准模块时&#xff0c;攻击者可以通过发送包含恶意构造range域的header请求&#xff0c;来获取响应中的缓存文件头部信息。在某些配置中&#xff0c;缓存文件头可能包含后端服务器的IP地址或其它敏感信息&#xff0c;从而导致信息泄露。 影响版本 Ngin…

Ubutntu 命令行界面显示UI 【FrameBuffer显示GuiLiteSample-Hello3D】

参考资料 https://www.cnblogs.com/jzcn/p/16898249.html https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3D https://github.com/idea4good/GuiLite 显示效果&#xff1a;&#xff08;看看左上角处立方体&#xff09; 使用场景&#xff1a; 嵌入式Linux…

《动手学深度学习 Pytorch版》 8.5 循环神经网络的从零开始实现

%matplotlib inline import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, vocab d2l.load_data_time_machine(batch_size, num_steps) # 仍然使用时间机器数据集8.…

深度学习验证码项目

项目代码&#xff1a; GitHub - kerlomz/captcha_trainer: [验证码识别-训练] This project is based on CNN/ResNet/DenseNetGRU/LSTMCTC/CrossEntropy to realize verification code identification. This project is only for training the model. GitHub - Python3WebSpi…

锂电池行业新技术,RFID技术赋能生产、溯源

随着新能源汽车用动力电池的快速扩大&#xff0c;对锂电池的发展高安全性、高一致性、高合格率和低制造成本提出了更高的要求。而RFID技术被广泛应用在锂电池行业&#xff0c;为锂电池的生产、管理、溯源等生产管理方面提供了极大地便利&#xff0c;提升了生产效率、产品质量和…

【工具软件】mediamtx——网页、vue3项目中播放 rtsp 视频流(支持265转码)

声明 本文只做 mediamtx 的使用实操&#xff0c;请务必参考下面的博客,&#xff0c;我也参考下面的大佬博客&#xff0c;感谢唯一602的无私分享&#xff1a; 在web页面中直接播放rtsp视频流&#xff0c;重点推荐&#xff1a;mediamtx&#xff0c;不仅仅是rtsp mediamtx 介绍 …

Vue的学习补充

1.Vue路由-404 作用&#xff1a;当路径找不到匹配时&#xff0c;给个提示页面 位置&#xff1a;配在路由最后 语法&#xff1a;path:*&#xff08;任意路径&#xff09;-前面不匹配就命中最后这个 2.Vue路由-模式设置 hash路由&#xff08;默认&#xff09; 例如&#xff…