『Linux小程序』进度条

文章目录

缓冲区问题

假设有一段代码为:

cpp 复制代码
#include<iostream>                                  
#include<unistd.h>                                                       
 int main()                              
 {                                                  
                                              
   std::cout<<"it's a file for Proc"<<std::endl;
  sleep(3);
  return 0;
 }         

编译后运行为正常,先打印后等待三秒结束程序;

但若是将其中的换行endl删除再次编译运行将会一样吗;

​ 答案为否 为什么不是先打印后sleep而是先sleep后打印呢 这里存在一个缓冲区问题
毋庸置疑的是,该处执行的顺序一定是先打印后sleep

​ 在这里确实是先进行打印而后再执行sleep,但是这里执行打印后并没有将信息显示出来;

​ 在c/C++中存在一个输出缓冲区(c/C++所提供的一段内存空间);

​ 这个输出缓冲区并并不是马上进行刷新,而是根据特定的刷新策略来进行刷新;

对于一般的显示器设备,一般的刷新策略即为遇到换行 时,就把换行前的所有字符全部进行显示
若是想直接进行刷新则可以调用

cpp 复制代码
fflush(stdout);

进行刷新;

​ 从该处可以看出,在程序遇到fflush(stdout)时马上进行了刷新;

​ 该函数即为立马刷新输出缓冲区;

​ 对于输出缓冲区来说一般是不会造成溢出的,当输出缓冲区到达一定的量时将会强制进行刷新,并将新数据写入进输出缓冲区;
同时,对于打印等函数来说并不是直接将内容直接打印到显示器上,而是通过打印函数暂时存储到了输出缓冲区中;

回车与换行的区别

在c/C++中,尤其是在c语言中,大多数人习惯使用'\n'进行换行;

但是其实来说,换行与回车是有区别的,对于换行来说,单换行并不能使光标回到最开始的位置;


而对于回车来说,回车的真正意义为归位,即将光标恢复到最开始的位置;


然而在大部分场景中,键盘中的回车键都会被默认为换行+回车;

即为换行后再将光标恢复到首位;

在c/c++中也是如此,'\n'将会默认为 换行+回车 ,即'\n' + '\r' ;

从该处可以进行一个实验;

cpp 复制代码
#include<iostream>  
#include<unistd.h>  
 int main()  
 {  
   int count = 5;  
   while(count>=0){  
     std::cout<<"当前剩余:"<<count<<std::endl;                           
     sleep(1);                             
     --count;                              
   }                                       
                                           
   return 0;                               
 }                   

运行后:


每次都会打印数据并进行换行回车,因为这里使用了endl,其功能与'\n'相同;

而若是将cout换成'\r'将会是什么情况?

当讲cout换成 '\r' 时则什么都不会打印;
原因即为;
'\r'只是纯回车,并不是换行,而缓冲区当遇到换行时才会进行刷新;

若是在此处加上fflush(stdout)将会进行每次回车的功能;

这次并不会每次都进行换行,而是每次进行回车,同时内容也将重新覆盖,从而得到一个类似于倒计时的功能;

进度条小程序

根据上述的所有内容可以制作一个进度条,即主要结合 '\r' 回车来进行操作;

cpp 复制代码
#include<iostream>
 #include<unistd.h>
 #define NUM 51
  int main()
 {
  char s[NUM];
   int count = 0;
  std::string C("|/-\\");
   while(count <  NUM){
 
     printf("[%-50s][%-4d%%][%c]\r",s,count*2,C[count%4]);

     fflush(stdout);
     s[count++] = '=';
     s[count+1] = '\0';  
     usleep(100000);
   }
     std::cout<<std::endl;
   return 0;
 }
相关推荐
Chennnng5 小时前
Ubuntu 安装过程的 6 大常见问题类型
linux·运维·ubuntu
阿干tkl5 小时前
传统网络与NetworkManager对比
linux·网络
Evan芙6 小时前
Linux 进程状态与进程管理命令
linux·运维·服务器
doris6106 小时前
2025年设备管理系统:智能运维成新标杆
运维
qsjming6 小时前
EXT4文件系统特性说明
运维
码农12138号6 小时前
Bugku HackINI 2022 Whois 详解
linux·web安全·ctf·命令执行·bugku·换行符
Joren的学习记录7 小时前
【Linux运维进阶知识】Nginx负载均衡
linux·运维·nginx
用户2190326527357 小时前
Java后端必须的Docker 部署 Redis 集群完整指南
linux·后端
胡先生不姓胡7 小时前
如何获取跨系统调用的函数调用栈
linux
Jtti7 小时前
服务器防御SYN Flood攻击的方法
运维·服务器