前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >linux系统程序--简单进度条实现

linux系统程序--简单进度条实现

作者头像
小志biubiu
发布2025-02-27 21:11:33
发布2025-02-27 21:11:33
3500
代码可运行
举报
运行总次数:0
代码可运行

一、屏幕缓冲区

屏幕缓冲区是指在输出设备(如终端或控制台)之前,数据被存储的内存区域。 应用程序将输出数据写入这个缓冲区,然后系统统一将缓冲区的内容刷新到屏幕上。缓冲区的使用提高了I/O操作的效率,因为它允许数据批量刷新,而不是每次输出都进行一次I/O操作。

1、缓冲区刷新模式:

缓冲区的刷新模式决定了什么时候会将缓冲区内容刷新到终端屏幕上。主要有以下几种模式:

全缓冲模式(Fully Buffered):
  1. 数据只有在缓冲区满时才会被刷新到屏幕上。通常用于文件I/O。
行缓冲模式(Line Buffered):
  1. 当遇到换行字符(LF, \n)时,缓冲区内容会被刷新到屏幕上。常见于终端I/O。
  2. 一些标准输出流(如stdout)在连接到终端时默认使用行缓冲模式。
无缓冲模式(Unbuffered):
  1. 数据每次写入缓冲区后立即被刷新到屏幕上。适用于需要实时输出的场景,如错误输出流(如stderr)通常是无缓冲的。

2、换行(LF, \n)和回车(CR, \r

在屏幕缓冲区的刷新以及终端输出中,换行字符和回车字符有着重要的作用:

换行(Line Feed, \n):

功能:将光标移到下一行。 在行缓冲模式下:

  1. 当输出流遇到换行字符时,缓冲区的内容会被立即刷新到屏幕上,从而实现行缓冲的机制。
  2. 在许多现代终端和编程环境中,输出一个换行字符通常意味着会将当前行的数据刷新到屏幕。
回车(Carriage Return, \r):

功能:将光标移动到当前行的起始位置(即行首),但不移动到下一行。 用途:

  1. 常用于覆盖同一行内容,如进度条或动态日志输出。输出回车字符后,下一次的输出会从行首开始,覆盖当前行的内容。

3、换行回车在屏幕缓冲区中的作用

行缓冲模式:换行字符(\n)会触发缓冲区刷新,将内容显示到屏幕上。

回车字符(\r:不触发缓冲区刷新,而是移动光标,通常与手动刷新缓冲区结合使用,以实现动态行更新。

缓冲区刷新模式(全缓冲、行缓冲和无缓冲)控制了何时将数据从缓冲区刷新到屏幕。

换行字符(\n: 在行缓冲模式下起到触发缓冲区刷新的作用,同时将光标移到下一行。

回车字符(\r: 将光标移动到行首,常用于覆盖当前行的内容,而不触发缓冲区刷新。

综合使用换行和回车字符,可以实现灵活的终端输出效果,特别在实时显示和动态更新场景中非常常见。

4、老式打字机

缓冲区刷新相当于老式打字机或写作文,当从左向右写满了会进行光标向左回退,换行,继续打印。

5、行缓冲区

接下来直接看代码

代码一!什么现象?
代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
#include <unistd.h> //sleep()函数头文件
int main()
{
	printf("hello linux!\n");
	sleep(3);
	return 0;
}

它会打印完hello linux! 换行后休眠三秒。

代码二!什么现象??
代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
#include <unistd.h>
int main()
{
	printf("hello linux!");
	sleep(3);
	return 0;
}

没有\n以后,程序等待了三秒打印出hello linux!

代码三!什么现象???
代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
#include <unistd.h>
int main()
{
	printf("hello linux!");
	fflush(stdout);
	sleep(3);
	return 0;
}

打印完hello linux!光标休眠三秒后结束程序。

二、倒计时程序

利用缓冲区特点我们简单实现一个倒计时程序

代码语言:javascript
代码运行次数:0
复制
#include
#include
int main()
{
	int i = 10;
	while(i >= 0)
	{
		printf("%-2d\r", i); // \n
		fflush(stdout);
		i--;
		sleep(1);
	} 
	printf("\n");
	return 0;
}

三、进度条代码

process.c

代码语言:javascript
代码运行次数:0
复制
#include "process.h"
#include <string.h>
#include <unistd.h>
#define NUM 101
#define STYLE '='
// vesion1
void process_v1()
{
	char buffer[NUM];
	memset(buffer, 0, sizeof(buffer));
	const char *lable="|/-\\";
	int len = strlen(lable);
	int cnt = 0;
	while(cnt <= 100)
	{
		printf("[%-100s][%d%%][%c]\r", buffer, cnt, lable[cnt%len]);
		fflush(stdout);
		buffer[cnt]= STYLE;
		cnt++;
		usleep(50000);
	} 
	printf("\n");
} 
// verison2
void FlushProcess(double total, double current)
{
	char buffer[NUM];
	memset(buffer, 0, sizeof(buffer));
	const char *lable="|/-\\";
	int len = strlen(lable);
	static int cnt = 0;
	
	// 不需要⾃⼰循环,填充#
	int num = (int)(current*100/total); // 11.0 / 1000
	int i = 0;
	for(; i < num; i++)
	{
		buffer[i] = STYLE;
	} 
	double rate = current/total;
	cnt %= len;
	printf("[%-100s][%.1f%%][%c]\r", buffer, rate*100, lable[cnt]);
	cnt++;
	fflush(stdout);
}

process.h

代码语言:javascript
代码运行次数:0
复制
#pragma once

#include <stdio.h>

void process_v1();
void FlushProcess(double total, double current);

main.c

代码语言:javascript
代码运行次数:0
复制
#include "process.h"
#include <stdio.h>
#include <unistd.h>

double total = 1024.0;
double speed = 1.0;

void DownLoad()
{
	double current = 0;
	while(current <= total)
	{
		FlushProcess(total, current);
		// 下载代码
		usleep(3000); // 充当下载数据
		current += speed;
	} 
	printf("\ndownload %.2lfMB Done\n", current);
} 

int main()
{
	DownLoad();
	DownLoad();
	DownLoad();
	DownLoad();
	DownLoad();
	DownLoad();
	DownLoad();
	DownLoad();
	return 0;
}

Makefile

代码语言:javascript
代码运行次数:0
复制
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
BIN=processbar

$(BIN):$(OBJ)
	gcc -o $@ $^
%.o:%.c
	gcc -c $<
.PHONY:
clean:
	rm -f $(OBJ) $(BIN)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、屏幕缓冲区
    • 1、缓冲区刷新模式:
      • 全缓冲模式(Fully Buffered):
      • 行缓冲模式(Line Buffered):
      • 无缓冲模式(Unbuffered):
    • 2、换行(LF, \n)和回车(CR, \r)
      • 换行(Line Feed, \n):
      • 回车(Carriage Return, \r):
    • 3、换行回车在屏幕缓冲区中的作用
    • 4、老式打字机
    • 5、行缓冲区
      • 代码一!什么现象?
      • 代码二!什么现象??
      • 代码三!什么现象???
  • 二、倒计时程序
  • 三、进度条代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档