【Linux】使用Linux实现小程序 - 进度条

news2024/11/24 12:14:57

在这里插入图片描述

目录

  • 一、缓冲区
  • 二、回车换行的概念
  • 三、进度条的设计
    • 3.1 版本1(没有配合场景)
    • 3.2 版本2(配合场景)
    • 3.3 版本3(美化进度条)
  • 结尾

一、缓冲区

C/C++语言,会针对标准输出,给我们提供默认的缓冲区,这里主要讲输出缓冲区,那么它在哪里呢?

在C语言中,输出缓冲区通常与标准I/O流(如stdout、stderr等)相关联。这些流在C标准库中通过FILE结构体来表示,而FILE结构体内部封装了文件描述符和缓冲区等信息。因此,当使用printf()等函数进行输出时,实际上是将数据写入到了与stdout流相关联的缓冲区中。

在这里插入图片描述
那么需要怎么证明呢?

当我们没有使用fflush刷新缓冲区时,printf()函数早已运行了,但是数据却没有立马显示出来,而是暂停了两秒钟才显示出来,因为printf()函数输出的数据在缓冲区中,所以没有立马显示出来,当暂停两秒钟后,程序结束,强制刷新缓冲区,才将缓冲区的内容输出。
在这里插入图片描述

那么有人也会问了,当我们使用 printf()函数输出数据时添加\n,也能立马输出数据这是为什么?
因为/n也是一种刷新策略,/n也叫做行刷新。


二、回车换行的概念

在这里向大家提一个问题,大家是否认为回车和换行是一个东西,其实不然,回车和换行是两个不同的概念,回车是将光标移回当前行的第一个位置,换行是将光标的位置移动到下一行,但光标的位置并不会移回行的第一个位置
在这里插入图片描述
在老式键盘中的回车换行也是比较形象的体现了回车和换行的特征。
在这里插入图片描述

那么我们在敲代码使用的 /r/n 分别是什么呢?
- /r 是回车,光标仅仅回到当前行的第一个位置。
- /n 是回车换行,光标即移回行的第一个位置,又移动到下一行。

在这里插入图片描述

那么下面写一份代码,除/r/n不同外其他部分全部相同,来看看程序的结果分别是什么。

在这里插入图片描述

在这里插入图片描述

我们通过上面的图片可以看到使用/n时,每一秒钟在下一行输出一个数字

而使用/r时,每一秒钟在当前行输出一个数字,并且覆盖上一个字符,最终被命令行覆盖,但是当循环时强制刷新缓冲区就可以把最后一个数字留下来,通过/r的这个特性,那么我们就可以设计倒计时,进度等。


三、进度条的设计

3.1 版本1(没有配合场景)

在这里插入图片描述

进度条效果图

在这里插入图片描述

// 	process.c
#include"process.h"                                                                                                                         
    
const char rotate[]={"|/-\\"};    
    
void process()    
{    
    char arr[SIZE] = {0};    
    int rate = 0;    
    int len = strlen(rotate);    
    while(rate <= MAX_RATE)    
    {    
        printf("[%-100s][%3d%%][%c]\r",arr,rate,rotate[rate%len]);    
        usleep(STIME);    
        arr[rate++]=STYLE;    
    }    
    
    printf("\n");    
}
//	process.h
#include<stdio.h>
#include <unistd.h>
#include<string.h>

#define STYLE '#'      // 进度条的风格
#define MAX_RATE 100   // 进度的最大值
#define SIZE 101       // 数组需要开多大 
#define STIME 1000*50  // 暂停的时间
                                                                                                                                        
void process();
//	main.c
#include"process.h"

int main()
{
	process();

	return 0;                                                                                                                           
 }
// 	Makefile
cc=gcc
src=main.c process.c                                                                                                                    
target=myprocess

$(target):$(src)
	$(cc) $^ -o $@

.PHONY:clean
clean:
	rm -f $(target)

3.2 版本2(配合场景)

无论任何进度条,一定和某种任务关联,那么这个版本的进度条不是在函数内部循环打印,而是通过回调的方式来进行某种任务的通知,动态进行更新进度条。

在这里插入图片描述

// 	process.c
#include"process.h"                                                                                                                         
      
const char rotate[]={"|/-\\"};      
      
void process2(int rate)      
{      
    static char arr[SIZE] = {0};      
    int len = strlen(rotate);      
    if(rate <= MAX_RATE && rate >= 0)      
    {      
        printf("[%-100s][%3d%%][%c]\r",arr,rate,rotate[rate%len]);  
        
        fflush(stdout);  
        
 		arr[rate]=STYLE;          
    }      
}      
// main.c
#include"process.h"    
    
#define TOTAL_SIZE 1024*1024  // 程序大小    
#define DSIZE 1024*10 // 下载速度                                                                                                           
    
void download()    
{    
    int target = TOTAL_SIZE;    
    int sum = 0;  // 当前下载总大小    
    while(sum <= TOTAL_SIZE)    
    {    
        int rate = sum*100/target;    
        process2(rate);    
        sum += DSIZE;    
        usleep(STIME);    
    }    
    
    process2(MAX_RATE);    
    
    printf("\n");    
}    
    
int main()    
{    
    download();    
    
    return 0;    
} 
//	process.h
#include<stdio.h>    
#include <unistd.h>    
#include<string.h>    
    
#define STYLE '#'      // 进度条的风格    
#define MAX_RATE 100   // 进度的最大值    
#define SIZE 101       // 数组需要开多大                                                                                                    
#define STIME 1000*50  // 暂停的时间    
    
typedef void(*callback_t)(int);    
    
void process1();    
void process2(int); 

3.3 版本3(美化进度条)

上面两个版本进度条中的旋转光标会受到进度的影响,在生活中下载软件、游戏等应用的时候可能在某个进度的时候突然卡住了,如果旋转光标会受到进度的影响的话,就不能知道软件是否在下载,所以当前版本对当前问题进行了优化,使旋转光标不再受到进度的影响。并且将进度的显示修改为小数。
在这里插入图片描述

进度条效果图

在这里插入图片描述

#include"process.h"    
    
const char rotate[]={"|/-\\"};    
    
void process3(double rate)    
{    
    static int rotate_cnt = 0;    
    static char arr[SIZE] = {0};    
    int len = strlen(rotate);    
    
    rotate_cnt = ++rotate_cnt % len;    
    
    if(rate < MAX_RATE && rate > 0)    
    {    
        arr[(int)rate-1]=STYLE_BODY;    
        arr[(int)rate]=STYLE_HEAD;    
    }    
    else if(rate == MAX_RATE)                                                                                                               
    {    
        arr[(int)rate]='\0';    
        arr[(int)rate-1]=STYLE_BODY;    
    }    
    printf("[%-100s][%6.2lf%%][%c]\r",arr,rate,rotate[rotate_cnt%len]);    
    fflush(stdout);    
} 
//	main.c
#include"process.h"                                                                                                                         
    
#define TOTAL_SIZE 1024*1024  // 程序大小    
#define DSIZE 1024*10 // 下载速度    
    
void download(callback_t cb)    
{    
    int target = TOTAL_SIZE;    
    int sum = 0;  // 当前下载总大小    
    while(sum <= TOTAL_SIZE)    
    {    
        double rate = sum*100.0/target;    
        cb(rate);    
        sum += DSIZE;    
        usleep(STIME);    
    }    
    
    cb(MAX_RATE);    
    
    printf("\n");    
}    
    
int main()    
{    
    download(process3) ;    
    
    return 0;    
}  
// 	process.h
#include<stdio.h>                                                                                                                           
#include <unistd.h>    
#include<string.h>    
    
#define STYLE '#'      // 进度条的风格    
#define MAX_RATE 100   // 进度的最大值    
#define SIZE 101       // 数组需要开多大     
#define STIME 1000*50  // 暂停的时间    
#define STYLE_HEAD '>'    
#define STYLE_BODY '='    
    
// typedef void(*callback_t)(int);    
typedef void(*callback_t)(double);    
    
void process1();    
void process2(int);    
void process3(double); 

结尾

如果有什么建议和疑问,或是有什么错误,大家可以在评论区中提出。
希望大家以后也能和我一起进步!!🌹🌹
如果这篇文章对你有用的话,希望大家给一个三连支持一下!!🌹🌹

在这里插入图片描述

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

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

相关文章

c++----杨辉三角(补充)

大家好。今天我给大家带来的是&#xff0c;我们以前讨论过的知识点。杨辉三角。我相信大家在c的学习中已经清楚的了解和认识到了杨辉三角的实现逻辑和实现方法了。但是应该大多局限于在c中吧。我们都知道我们c与c其实在一些地方是可以相互成就的。那么我们在c中的经典题目杨辉三…

自定义实现log4j的appender

log4j&#xff0c;应用最广泛的日志框架。其作者后来推出logback&#xff0c;也是好选择。不多说废话。 log4j组件介绍 Log4j主要有三个组件&#xff1a; Logger&#xff1a;负责供客户端代码调用&#xff0c;执行debug(Object msg)、info(Object msg)、warn(Object msg)、err…

oracle----undo表空间

文章目录 undo表空间概念和作用undo表空间主要用于解决&#xff1a;1.1 读一致性1.2 回滚事务1.3 实例恢复 undo表空间操作查看UNDO表空间查看UNDO 参数查看undo表空间文件位置 undo表空间概念和作用 对于DML语句&#xff0c;只要修改了数据块&#xff0c;数据库就会把修改前的…

使用Amazon SageMaker JumpStart微调Meta Llama 3.1模型以进行生成式AI推理

文章目录 使用Amazon SageMaker JumpStart微调Meta Llama 3.1模型以进行生成式AI推理Meta Llama 3.1SageMaker JumpStartSageMaker JumpStart中Meta Llama 3.1模型的微调配置使用SageMaker JumpStart UI进行无代码微调使用SageMaker JumpStart SDK进行微调结论 使用Amazon Sage…

电商数据整合新篇章:京东商品详情API返回值应用实践

电商数据整合在当今商业环境中具有重要地位&#xff0c;API&#xff08;应用程序编程接口&#xff09;提供了高效收集、整合和分析数据的途径。以京东商品详情API为例&#xff0c;通过其返回值&#xff0c;电商企业可以构建更精准的营销策略、优化产品以及提升用户体验。以下是…

实例分割【YOLOv8版】

参考文档 Segment - Ultralytics YOLO Docs​docs.ultralytics.com/tasks/segment/ 何为实例分割&#xff1f; 实例分割比目标检测更进一步&#xff0c;涉及识别图像中的各个对象并将它们与图像的其余部分分割开来。 实例分割模型的输出是一组用于勾勒图像中每个对象的掩码…

回溯法-图的m着色问题

图的 m 着色问题 问题描述 给定一个无向连通图 ( G (V, E) ) 和 ( m ) 种颜色&#xff0c;我们的任务是为图 ( G ) 的每个顶点着色&#xff0c;使得相邻的顶点颜色不同。如果存在这样的着色方案&#xff0c;我们称之为图 ( G ) 的 ( m ) 可着色问题。 算法思路 初始化&…

Sentence-BERT实现文本匹配【回归目标函数】

引言 上篇文章我们通过Sentence-Bert提出的分类目标函数来训练句子嵌入模型&#xff0c;本文同样基于Sentence-Bert的架构&#xff0c;但改用回归目标函数。 架构 如上图&#xff0c;计算两个句嵌入 u \pmb u u和 v \pmb v v​之间的余弦相似度&#xff0c;然后可以使用均方误…

如何通过住宅代理优化SERP表现:提升SEO排名的实用指南

引言 什么是SERP&#xff1f;包含哪些内容&#xff1f; 为什么SERP对SEO至关重要&#xff1f; 如何优化SERP表现&#xff1f; 总结 引言 在当今竞争激烈的数字营销环境中&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已成为企业提升在线可见性和吸引有机流量的关键…

matlab2024a/2023/2022/2020/matlab2019 如何plot画局部放大图(已解决)

matlab 2024&#xff1b;matlab 2023&#xff1b;matlab 2022&#xff1b;matlab 2021&#xff1b;matlab 2020&#xff1b;matlab 2019 matlab 2017一下的 使用magnify.m 进行局部放大图操作是没有问题的。 新版本 采用magnify.m 很难操作。 为什么要局部放大 局部方…

【王树森】Few-Shot Learning (3/3):Pretraining + Fine Tuning(个人向笔记)

Preliminary Few-Shot Learning 很简单&#xff0c;但是却能达到比较高的准确度&#xff0c;相反一些复杂的模型反而不能达到很高的准确率 1. Cosine Similarity 余弦相似度可以衡量两个向量的相似度 假设两个向量的长度都是1&#xff1a;那么它们余弦相似度的计算方法如下…

HarmonyOS开发实战( Beta5版)线程间通信场景最佳实践

简介 在应用开发中&#xff0c;经常会需要处理一些耗时的任务&#xff0c;如果全部放在主线程中执行就会导致阻塞&#xff0c;从而引起卡顿或者掉帧现象&#xff0c;降低用户体验&#xff0c;此时就可以将这些耗时操作放到子线程中处理。通常情况下&#xff0c;子线程可以独立…

bcftools报错|The sequence “chr1“ not defined in the header: chr1.recode.vcf

1、报错信息 The sequence "chr1" not defined in the header: chr1.recode.vcf (Quick workaround: index the file.) 所使用的命令&#xff0c;目的是想合并所提取的特定染色体。 bcftools concat -O v / -o varscan.indel_merged.vcf chr1.recode.vcf chr2.reco…

超好用的图纸加密软件排行榜 | 2024图纸加密软件的七款最优选择!

数字化设计日益普及的今天&#xff0c;图纸作为设计与工程的核心载体&#xff0c;其安全性成为了企业和设计师们最为关注的焦点之一。 面对日益复杂的数据泄露风险&#xff0c;如何有效地保护图纸文件的安全呢&#xff1f; 下面&#xff0c;我们就来探讨一下2024图纸加密软件的…

Python的10个文件对比与合并高效策略

文末赠免费精品编程资料~~ 在日常编程或数据分析工作中&#xff0c;经常需要处理多个文件的对比与合并任务。Python因其强大的文件处理能力和丰富的库支持&#xff0c;成为了处理这类任务的理想选择。下面&#xff0c;我们将逐步探索10种高效的文件对比与合并策略&#xff0c;…

OpenGL/GLUT实践:粒子系统,并添加纹理、动态模糊、边界碰撞(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub&#xff1a;A-UESTCer-s-Code 文章目录 1 运行效果2 实验过程2.1 基本粒子系统2.1.1 定义粒子结构2.1.2 创建粒子并初始化2.1.2.1 创建粒子2.1.2.2 初始化 2.1.3 粒子状态更新与绘制2.1.3.1 绘制2.1.3.2 更新 2.1.4 实现效果 2.2 添加纹理2.2.1 纹理添加2.2.2 渲染…

PostgreSQL + PostGIS:空间数据存储及管理解决方案

在数据库领域&#xff0c;PostgreSQL 已成为最强大、最通用的选项之一。它管理大量数据的能力、对 SQL 标准的遵守以及可扩展的架构使其受到学术界和工业界的喜爱。然而&#xff0c;真正让 PostgreSQL 脱颖而出的原因之一是它与PostGIS的集成&#xff0c;这是一个允许您有效处理…

第七课,条件表达式与初识分支判断

一&#xff0c;什么是判断 判断&#xff0c;就是在做某件事前&#xff0c;先问问满不满足条件。 进行逻辑判断&#xff0c;是生活中常见的行为。 “今天出门你要带伞吗&#xff1f;” “那得看天气怎么样&#xff0c;如果下雨或者太阳太大就带伞&#xff0c;否则就不带。”…

内存卡乱码问题解析恢复方案

一、内存卡乱码现象探析 在数字化时代&#xff0c;内存卡作为便携式数据存储设备&#xff0c;广泛应用于手机、相机、行车记录仪等多种电子设备中。然而&#xff0c;不少用户在使用过程中会遇到内存卡乱码的问题&#xff0c;即原本有序存储的文件突然变得无法识别&#xff0c;…

【前端面试】设计循环双端队列javascript

题目 https://leetcode.cn/problems/design-circular-deque/description/ 存储循环队列的向量空间是循环的,用通俗的话来讲,就是我们在做next或者prev操作时,不会发生溢出 取模、或者直接判断是否为0/size返回一个值。 数组实现 用函数来实现一个类,定义容量、头尾指针…