LINUX——进度条

回车与换行的概念

其实在C语言中学的'\n'(即回车换行)其实是两个动作,即回车(回到这行的第一个位置)和换行(从末尾位置向下移动一行)。

键盘上的回车键是先向下,再向左的。

在C语言中,'\n'是回车换行,而'\r'仅仅是回车。

行缓冲区

大家可以自己编译一下下面两个代码,看看现象有什么不一样。

现象是1图先打印三秒后再休眠,2图则是休眠了三秒后,等到结束程序时,再把字符串显示了出来。

对于2图的现象我们要知道,程序并不是先执行sleep函数,再执行printf函数。程序是从上往下执行的,那么在休眠时间里字符串去哪了呢?答案是被放在了缓冲区里。

缓冲区实质上就是一块内存空间,上面的字符串就是保存在这样的一块内存空间里,当程序运行结束时,会自动刷新缓冲区里的内容到显示器上面。

那为什么1图就能直接刷新呢?这要说到刷新缓冲区的几种方法了。

  1. 在行尾加上'\n',立即刷新
  2. 等待缓冲区满或者程序结束,自动刷新
  3. 强制刷新(C语言提供了一个fflush函数,用于强制刷新缓冲区)

我们知道程序在运行的时候默认会打开三种流:

  • 标准输入流,stdin
  • 标准输出流,stdout
  • 标准错误流,stderr

我们的显示器对应的就是标准输出文件,Linux下一切皆文件!

当我们使用fflush函数时,也是先打印再休眠。

有了上面的程序我们可以先来实现一个简易倒计时程序:

简易倒计时

复制代码
#include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   int i=10;
  6   while(i>=0)
  7   {
  8     printf("倒计时:%-2d\r",i);
  9     fflush(stdout);
 10     sleep(1);                                                                                                                                                                                                
 11     i--;                
 12   }                     
 13   printf("\n");         
 14   return 0;    

进度条代码

为了方便文件的管理,我们这里采用多文件的形式去实现。

复制代码
//procs.c
#include"procs.h"
#include<string.h>
#include<unistd.h>
#define style '-'
#define len 101
void procs()
{
  char num[len];
  memset(num,0,sizeof(num));
  int cnt=0;
  while(cnt <= 100)                                                                                                                                                                                          
    {
      printf("[%-100s][%3d%%]\r",num,cnt);
      fflush(stdout);
      num[cnt]=style;
      cnt++;
      usleep(50000);
    }
  printf("\n");
}
 
//.h
#pragma once                                                                                                                                                                                                 
  2 #include<stdio.h> 
  3 void procs();

//test.c
#include"procs.h"                                                                                                                                                                                            
  2 #include<stdio.h> 
  3 int main()        
  4 {                
  5   procs();
  6   return 0;
  7 }

 //makefile                                                                                                                                                                                       
  1 bin=procs.exe
  2 src=procs.c test.c
  3 $(bin):$(src)
  4   gcc -o $@ $^
  5 .PHONY:clean
  6 clean:
  7   rm -rf $(bin)  
相关推荐
wdfk_prog8 小时前
大型 Docker 镜像导出导入工程化:可靠性、磁盘与压缩
运维·docker·容器
回忆2012初秋8 小时前
DBX:一个现代化的轻量级、跨平台的开源数据库管理工具
大数据·服务器·网络
fengkai45458 小时前
七、华为云网络综合实验 & 运维类及其他服务总结
服务器·开发语言·php
郝开8 小时前
Docker Compose 模块化多环境配置规范指南:示例搭建Alf Tengine MD2DOC 1.1.1
运维·docker·容器
2601_962063239 小时前
THPX信号源:服务支持系统与品牌运营节奏带来的平台印象
运维
JeJe同学9 小时前
Linux远程服务器网络访问优化:使用SSH反向端口转发共享本地HTTP代理
服务器·网络·ssh
光电笑映9 小时前
Linux 线程同步与互斥:锁的本质、条件变量与信号量的底层原理
linux·运维·服务器·开发语言·c++
AI职业加油站9 小时前
2026大数据运维行业趋势复盘:大数据运维工程师赋能发展
大数据·运维·人工智能·学习·数据分析·职场发展
kaoa0009 小时前
Linux入门攻坚——89、Hadoop-1-架构及概念
大数据·linux·hadoop·分布式
吉甫作诵9 小时前
Oracle 19c 常用运维命令大全
运维·数据库·oracle