Linux的vim下制作进度条

news2025/1/8 4:26:17

目录

前言:

回车和换行有区别吗?

回车和换行的区别展示(这个我在Linux下演示)

为什么会消失呢? 

回车和换行的区别

为什么'\r'和'\n'产生的效果不同?

 打印进度条:

(1)打印字符串

(2)显示百分数

(3)完结撒花 


前言:

在这里我要问大家一个问题,请问:

回车和换行有区别吗?

有些人的回答是:我感觉没区别啊,Enter键就是回车,我平时按了就换行了

有些人的回答是:有区别,但是我也具体说不出来,但是在C语言里,换行是'\n',但是回车却是'\r'

其实答案是:有区别

回车和换行的区别展示(这个我在Linux下演示)

但我们在一个test.c文件中写入如下代码时:

  #include <stdio.h>
  #include <unistd.h>//注意头文件
   
   int main()
   {
     printf("Hello 努力的你\n");      
     sleep(3);                                                                                                                       
     return 0;                                                                                                               
   } 

会输出

Hello 努力的你

并且停顿三秒 (停顿时如下所示)

这并不稀奇,但是你将代码里的'\n'换为'\r'时,如下

  #include <stdio.h>
  #include <unistd.h>//注意头文件
   
   int main()
   {
     printf("Hello 努力的你\r");      
     sleep(3);                                                                                                                       
     return 0;                                                                                                               
   } 

你同样会发现停顿了三秒,但并未输出任何东西(停顿时如下所示)

但当在sleep(3);之前加入

fflush(stdout);

{

关于fflush的原型的查看,C语言中我们右cplusplus,或者MSDN,但在Linux下,Linux自带了功能查询,我们可以在命令行中输入以下代码来查看相应功能(要退出,则输入:q

要上下翻:用键盘的上下键(千万不要用鼠标哦,自己可以试试看哦,在Linux下,鼠标大多是没用的))

man fflush
//man 命令:可以查看该命令的具体信息

 将会出现如下信息

是不是和cplusplus和MSDN很像 

这里我们看出fflush属于<stdio.h>这个文件

它的参数为一个文件指针(Linux内部,一切视为文件

而我们这里需要把stdout(标准输出流)作为参数(后面会说为什么)

 代码如下所示:

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 
  4 int main()
  5 {
  9   printf("Hello 努力的你\r");
 10   fflush(stdout);  
 11   sleep(3);
 14   return 0;       
 15 }   

这时会显示出“Hello 努力的你”

细心的你可能会发现,这里的光标并不像往常一样在打印的这句话的最后,而是在开头

而这个代码  被执行  到  执行完  经历了以下过程

先打印“Hello 努力的你”,再停顿3秒, “Hello 努力的你”再消失不见

为什么会消失呢? 

这就回到了我们一开始的问题: 回车和换行有区别吗?

答案也公布了,是有的

回车和换行的区别

在一些键盘中,Enter键可能会是如下样子:

大家有没有思考过,明明是换行功能,它为什么还有个转折呢?

如果用画图来表示换行,那将是这个样子:

 

只是行变了,列并没有变

但是回车,就是如下样子:

 

行变了,而到了新一行的开头

(这也是为什么键盘的Enter键长那个样子的原因

这就是换行和回车的不同

为什么'\r'和'\n'产生的效果不同?

*为什么'\r'时就不显示任何东西呢(没有fflush的情况下)

     *这里要讲到缓冲区的概念

     *因为在计算机内部,如果每次输出直接输出到屏幕,是非常慢的,因为它是外部设备,输出需要用到CPU的运行,但是一个计算机的快慢也满足短板原理,慢的步骤会决定整个步骤的快慢,

在计算机中速度由快到慢是:

CPU > 内存 > 磁盘

我们不能只要要输出就占用CPU资源,这就需要设置一个区域专门的区域来存储即将输出的数据,而内存就是一个比较高性价比的地方,速度不快不慢,价格也适中,这就有了缓冲区

而我们经常做的printf语句输出的内容通常并不是该语句执行完了就立马打印,而是先放在缓冲区再打印,但是为什么平时看起来是立马打印呢?😶😶😶

因为我们通常会在printf的语句的最后加上一个'\n',当遇到'\n'时计算机会自动刷新缓冲区的内容到输出设备,而我们的printf就是输出到显示器,这就是为啥printf完就立马输出的原因(⊙o⊙)!!!me懂了

但是'\r'并不和'\n'一样具有刷新缓冲区的功能(●ˇ∀ˇ●),它将要打印的语句放进了缓冲区,当程序快结束时,再输出,但是'\r'会将光标移到一行的开头!!!!!!!!!.......Σ(っ °Д °;)っ哇哦,所以当要打印时,显示器上会显示光标前的内容,并清空缓冲区,但是光标已经在缓冲区的开头,所以没有输出任何东西ฅʕ•̫͡•ʔฅ

fflush的作用(⊙o⊙)????

这个也在之前的man fflush的文件中写了

翻译ヾ(≧▽≦*)o: 对于输出流,fflush()通过流的底层写函数强制为给定的输出或更新流写入所有用户空间缓冲数据。对于输入流,fflush()将丢弃从底层文件中获取但尚未被应用程序使用的任何缓冲数据。流的打开状态不受影响。

也就是说会打印缓冲区的内容,并刷新缓冲区

而我们的“Hello 努力的你”就在缓冲区里,所以被打印了出来,但是'\r'还是让光标回到了打印的语句的最开头,所以sleep三秒后,缓冲区的刷新,让“Hello 努力的你”这句话不见了

不知道到这里你看懂了吗?你可是看了快两千字了哦,太厉害了吧,夸夸自己(/≧▽≦)/,给你赞一个d=====( ̄▽ ̄*)b

 现在就要讲各位心心念念的进度条的实现啦~~~

先看看效果啦~~(转gif失败了(哭哭){{{(>_<)}}}

 

首先进度条是一个字符串,因此,要设置一个字符串

char jin_du_tiao[150];

同时我们要控制它的进度条的#个数不断增加----->需要一个循环来给进度条不断增加字符----->不能无限循环,要有退出条件----->设置一个变量,当这个变量长度为100时就退出循环

while (cnt <= 100)
  {
    jin_du_tiao[cnt++] = '#';
  }

 打印进度条:

(1)打印字符串

while (cnt <= 100)
  {
    printf("%s\n", jin_du_tiao);
    jin_du_tiao[cnt++] = '#';
  }

(2)显示百分数

在格式输出中,显示百分号用:

%%
while (cnt <= 100)
  {
    printf("%s%d%%\n", jin_du_tiao, cnt);
    jin_du_tiao[cnt++] = '#';
  }

 但是这样子打印出来的结果是😥:

0%
#1%
##2%
.
.
.

################################################################100%

谁家进度条的进度跟着进度条走啊😣😣,何况进度条走那么快,谁看得清那个数字😫啊,而且 数字 和 # 紧紧挨在一起一点都不好看😡

这就用到了格式控制符    .......ε=ε=ε=(~ ̄▽ ̄)~

while (cnt <= 100)
  {
    printf("[%-100s][%d%%]\n", jin_du_tiao, cnt);// -:左对齐     100:让后面的百分比不会跟着进度条跑     %%:显示百分号
    jin_du_tiao[cnt++] = '#';
  }

-:左对齐     100:让后面的百分比不会跟着进度条跑     %%:显示百分号

但是这样子打印出来的效果是:

[ ]                                                                                                                                        [0%]

[#]                                                                                                                                       [1%]

[##]                                                                                                                                    [2%]

.

.

.

.

[#################################################################][100%] 

没有左对齐时: 

[                                                                                                                                        ] [0%]

[                                                                                                                                      #] [1%]

[                                                                                                                                    ##] [2%]

.

.

.

.

[#################################################################][100%] 

谁家进度条一行一行的啊  ╰(‵□′)╯,进度条不应该在一行吗?

欸嘿,这里就用到了'\r'啦~~~~,'\r'起到了从头开始打印的效果

while (cnt <= 100)
  {
    printf("[%-100s][%d%%]\r", jin_du_tiao, cnt);// -:左对齐     100:让后面的百分比不会跟着进度条跑     \r:有刷新的效果    %%:显示百分号
    jin_du_tiao[cnt++] = '#';
    fflush(stdout); //一定记得要fflush(stdout)
  }

 但是这样你会发现,当你一执行就会显示完整的进度条     (。・・)ノ

[#################################################################][100%] 

所以让它sleep一下下~~~~~,可是sleep就比较懒(。>︿<)_θ,很慢,这样子打印进度条就超慢,这样子使用者恨不得卸载软件啦    ~Σ(っ °Д °;)っ

那就换个勤快点的吧:usleep 

sleep:以秒为单位

usleep:以微秒为单位

(3)完结撒花 

int main()
{
  int cnt = 0;
  char jin_du_tiao[150];
  while (cnt <= 100)
  {
    printf("[%100s][%d%%]\r", jin_du_tiao, cnt);// -:左对齐     100:让后面的百分比不会跟着进度条跑     \r:有刷新的效果    %%:显示百分号
    jin_du_tiao[cnt++] = '#';
    fflush(stdout); //一定记得要fflush(stdout)
    usleep(300000);//usleep(300000):以毫秒为单位      注意包含头文件:<unistd.h>
  }
  return 0;
}

哦吼吼,太酷了,你快看了四千字哦,给你大大的赞哦 👍,我也和这几千字合个影吧(写了快四个小时)✌😀✌

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

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

相关文章

第十四届蓝桥杯国赛:2023次方的思考(指数塔,数论)

首先我们要知道&#xff0c;正常计算的话&#xff0c;指数优先级最高&#xff0c;因此得先计算指数&#xff0c;比如&#xff1a; 2 3 2 512 2^{3^2}512 232512 欧拉定理的关键在于&#xff0c;它允许我们通过减少计算的指数大小来简化模运算。 经过仔细研究&#xff08;看题…

设计模式之代理模式ProxyPattern(六)

一、代理模式介绍 1、什么是代理模式&#xff1f; 代理模式是一种结构型设计模式&#xff0c;它允许为其他对象提供一个替代品或占位符&#xff0c;以控制对这个对象的访问。 2、代理模式的角色构成 抽象主题&#xff08;Subject&#xff09;&#xff1a;定义了真实主题和代…

【算法】【单调栈】【leetcode】1019. 链表中的下一个更大节点

刷这题之前先看&#xff1a; 【算法】【OD算法】【单调栈】找朋友-CSDN博客 【算法】【单调栈】【leetcode】1475. 商品折扣后的最终价格-CSDN博客 【算法】【单调栈】【leetcode】901. 股票价格跨度-CSDN博客 【算法】【单调栈】每日温度-CSDN博客 题目地址&#xff1…

机器人系统ros2-开发实践04-ROS2 中 tf2的定义及示例说明

1. what ros2 tf2 &#xff1f; tf2的全称是transform2&#xff0c;在ROS&#xff08;Robot Operating System&#xff09;中&#xff0c;它是专门用于处理和变换不同坐标系间位置和方向的库。这个名字来源于“transform”这个词&#xff0c;表示坐标变换&#xff0c;而“2”则…

【介绍下Unity编辑器扩展】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

学习 Rust 第 23 天:闭包

Rust 闭包提供了简洁、富有表现力的匿名函数来捕获周围的变量。它们简化了代码&#xff0c;提供了存储、参数传递和函数重构方面的灵活性。它们与泛型的交互增强了灵活性&#xff0c;而捕获模式则促进了有效的所有权和可变性管理。从本质上讲&#xff0c;闭包是 Rust 的基础&am…

笔记-用Python脚本启停JAR程序

用Python脚本启停JAR程序&#xff0c;需要用到python中的以下内置模块 subprocess 是 Python 的一个标准库模块&#xff0c;用于在新进程中执行子命令&#xff0c;获取子进程的输入/输出/错误以及返回码等os 是 Python 的一个标准库模块&#xff0c;它提供了与操作系统交互的功…

【web安全】-- 命令执行漏洞详解

本文将从原理开始介绍命令执行漏洞并附有三个实例来供各位客官学习 文章目录 一、什么是命令执行漏洞二、出现的原因三、有可能存在命令执行漏洞的函数&#xff08;php&#xff09;1、利用一些函数来实现命令执行2、直接执行系统命令的函数 四、命令拼接符号1、Windows2、linux…

【Mac】mac 安装 prometheus 报错 prometheus: prometheus: cannot execute binary file

1、官网下载 Download | Prometheus 这里下载的是prometheus-2.51.2.linux-amd64.tar.gz 2、现象 解压之后启动Prometheus 启动脚本&#xff1a; nohup ./prometheus --config.fileprometheus.yml > prometheus.out 2>&1 & prometheus.out日志文件&#xff…

opencv基础篇 ——(十)非真实感渲染

非真实感渲染&#xff08;Non-Photorealistic Rendering, NPR&#xff09;是指通过一系列图像处理技术&#xff0c;将真实感图像转换为具有特定艺术风格或视觉效果的图像&#xff0c;模拟绘画、素描、卡通等非现实主义表现手法。OpenCV 提供了一些内置函数来实现非真实感渲染&a…

医疗大模型华佗GPT-2:医学问答超越GPT-4,通过2023年国家执业药师考试

前言 随着人工智能技术的快速发展&#xff0c;特别是在自然语言处理(NLP)领域&#xff0c;大型预训练模型如GPT系列已经显示出在多个领域的强大应用潜力。最近&#xff0c;华佗GPT-2医疗大模型的发布&#xff0c;不仅标志着人工智能在医学领域的一大进步&#xff0c;更是在202…

Linux IP Forwarding路由转发实验

linux 路由转发功能 Linux 操作系统具备路由转发功能&#xff0c;路由功能是指 Linux 操作系统提供的路由管理和转发功能&#xff0c;它允许 Linux 主机在网络中正确地转发数据包&#xff0c;并确保数据包能够达到其目的地。 出于安全考虑&#xff0c;Linux系统默认是禁止数据…

vscode 检查更新 没有检查更新按钮

vscode 检查更新 没有检查更新按钮 1、问题描述2、问题分析3、解决方法 1、问题描述 今天在使用vscode写markdown文档时&#xff0c;需要粘贴图片到markdown文档中&#xff0c;结果无法粘贴进来&#xff0c;显示如下&#xff1a;只粘贴了image.png这几个字。 2、问题分析 搜索…

交通运输智慧监管平台---强化物流安全与效率的新举措

一、建设背景 随着社会对于交通安全和环境保护的要求不断提高&#xff0c;对卡车运输的监管和合规性要求也逐渐加强。为了满足快速发展的物流需求&#xff0c;提高供应链协同和可追溯性、解决安全问题、提高运输效率和降低成本&#xff0c;我们利用现代技术和信息化手段着力建设…

QT - 创建Qt Widgets Application项目

在Qt中结合OpenGL使用&#xff0c;可以创建一个Qt Widgets应用程序项目。在创建项目时&#xff0c;您可以选择使用OpenGL模板来生成一个已经集成了OpenGL的项目。这个模板会自动帮助您集成OpenGL和Qt&#xff0c;并生成一个基本的OpenGL窗口。您可以在这个窗口中进行OpenGL的开…

搭建大型分布式服务(三十七)SpringBoot 整合多个kafka数据源-取消限定符

系列文章目录 文章目录 系列文章目录前言一、本文要点二、开发环境三、原项目四、修改项目五、测试一下五、小结 前言 本插件稳定运行上百个kafka项目&#xff0c;每天处理上亿级的数据的精简小插件&#xff0c;快速上手。 <dependency><groupId>io.github.vipjo…

Spark SQL编程初级实践

参考链接 Spark编程: Spark SQL基本操作 2020.11.01_df.agg("age"->"avg")-CSDN博客 RDD编程初级实践-CSDN博客 Spark和Hadoop的安装-CSDN博客 1. Spark SQL基本操作 { "id":1 , "name":" Ella" , "age":…

深入理解正则表达式:从入门到精通

title: 深入理解正则表达式&#xff1a;从入门到精通 date: 2024/4/30 18:37:21 updated: 2024/4/30 18:37:21 tags: 正则Python文本分析日志挖掘数据清洗模式匹配工具推荐 第一章&#xff1a;正则表达式入门 介绍正则表达式的基本概念和语法 正则表达式是一种用于描述字符串…

Docker安装Nginx端口映射|挂载目录查看

文章目录 前言Docker安装nginx怎么查看端口映射|挂载映射 前言 Docker 的作用主要体现在应用隔离、跨平台部署、快速部署、环境一致性以及资源隔离和管理等方面&#xff0c;为软件开发和运维带来了很多便利和优势。 在服务器&#xff08;虚拟机&#xff09;中安装 Nginx、MyS…

从源头上减少BUG:掌握Java中的label和assert语句!

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…