Linux第一个系统程序-进度条

文章目录


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、回车与换行

我们常说的回车换行其实是两个概念

  • 回车概念(\r)

全称Carriage Return ,计算机定义:光标/字符位置回到本行行首,不改变行数

cpp 复制代码
printf("abc\r123");

最终屏幕显示:

cpp 复制代码
123
  1. 输出abc,光标此时在c的后面
  2. 遇到\r(回车),光标直接移动到本行行首,但不换行
  3. 屏幕此时还是abc,但是,光标已经在a的前面了
  4. 再输出123,此时光标在3的后面,也就意味着新输出的123分别把原先的abc给覆盖了

不是没输出abc,而是被123覆盖,因为中间有个回车符号

  • 换行概念(\n)

全称Line Feed ,计算机定义垂直向下移动一行,不改变水平位置

cpp 复制代码
printf("abc\n123");

最终屏幕显示:

cpp 复制代码
abc
   123
  1. 输出abc,此时光标在c的后面
  2. 换行符\n后,光标垂直往下移动一格
  3. 输出123,最终光标在3的后面
  • 老式打字机的例子
术语 符号 ASCII码值 打字机时代的物理含义
回车(Carriage Return) \r 13 让 "字车"(装着纸的架子)回到当前行的最左侧,不移动纸张
换行(Line Feed) \n 10 让纸张向下移动一行,不改变字车的水平位置

二.行缓冲区

要想理解行缓冲区,咱们先来看几段代码的现象,再来总结

cpp 复制代码
#include<stdio.h>
#include<unistd.h>
int main()
{
	printf("hello czh\n");
	sleep(3);
	return 0;
}

现象

cpp 复制代码
hello czh
czh@VM-0-3-ubuntu:~/vscode/code5-21$ 

hello czh碰到\n换行,直接打印出内容,休眠三秒后,程序运行结束

cpp 复制代码
#include<stdio.h>
#include<unistd.h>
int main()
{
	printf("hello czh");
	sleep(3);
	return 0;	
}

现象

cpp 复制代码
hello czhczh@VM-0-3-ubuntu:~/vscode/code5-21$ 

自程序运行起,休眠三秒后,内容hello czh才被打印出来

cpp 复制代码
#include<stdio.h>
#include<unistd.h>

int main()
{
	printf("hello czh");
	fflush(stdout);
	sleep(3);
	return 0;
}

现象

cpp 复制代码
hello czhczh@VM-0-3-ubuntu:~/vscode/code5-21$ 

立马刷新hello czh,休眠三秒后程序运行,才打印出命令行


缓冲区

我们在使用函数对所有向外(显示器、文件、网络、管道)打印时,通常会将内容先存放在一个叫做缓冲区的东西 。而我们的显示器刷新方式一般是行缓冲,也就是当缓冲区被写满时,数据就会被刷新出来。

那怎么样才能使得缓冲区中的东西刷新到显示器中呢?

  1. 一般写到这个缓冲区满了之后,才会向文件刷新出来(也就是行刷新
  2. 再者就是我们手动让内容刷新到,也就是fflush(stdout)换行符(\n)

2.1倒计时程序

懂得了回车换行,以及缓冲区的概念,我们来试着写一个倒计时

要求打印10-1,并且打印完才换行。

cpp 复制代码
#include<stdio.h>
#include<unistd.h>

int main()
{
	int count = 10;
	while(count)
	{
		printf("%-2d",count);
		fflush(stdout);
		printf("\r");
		count--;
	}
	printf("\n");
	return 0;
}

这里的代码有几处需要跟大家强调一下

因为是打印倒计时,所以循环体中不能有换行符,所以只能是先往缓冲区输入数字,再立即刷新到显示器中

然后再回车 ,让光标移动到开头,再向缓冲区写数字,再刷新到显示器,等全部数字打印完毕,再换行打印出命令行

这里有一个细节,可以帮大家更好的理解回车概念

就是回车,它仅仅只是回车,也就移动光标,仅此而已,它并不会把先前的数据抹掉,什么意思呢?

也就是说,当你第一次打印完10之后,回车光标回到开头 ,你再去打印9的时候,它把原先10当中的1给覆盖了,所以第二次打印出来的结果是90

图片解析:

怎么解决这个问题呢?

调整打印格式就好了

printf("%-2d",count);就能解决,-2标识向左对齐,不够两位数的空格来补,大于等于两位正常输出

cpp 复制代码
printf("%-2d\n", 5);   // 输出:5_ (5后面跟1个空格,左对齐)
printf("%-2d\n", 12);  // 输出:12 (刚好2位,正常输出)
printf("%-2d\n", 123); // 输出:123(超过2位,原样输出)

所以当打印数字9时,后面那个0就被空格替代了,就能看到9,而不是90了

三、进度条程序

3.1main.c

cpp 复制代码
#include"process.h"
#include<stdio.h>
#include<unistd.h>

double total = 1024.0;//总共需要的下载量
double speed = 1.0;//速度是每次为1

void DownLoad()
{
    double cur = 0;
    while(cur <= total)
    {
        FlushProcess(total,cur);
        usleep(3000);
        cur += speed;
    }
    printf("\ndownload %.2lfMB Done\n",cur);
}
int main()
{
    DownLoad();
    return 0;
}

3.2process.h

cpp 复制代码
#pragma once
#include<stdio.h>

void FlushProcess(double total,double cur);

3.3process.c

cpp 复制代码
#include"process.h"
#include<string.h>
#include<unistd.h>

#define NUM 101
#define STYLE '='

void FlushProcess(double total,double cur)
{
    char buffer[NUM];
    memset(buffer,0,sizeof(buffer));//数组元素全设为字符0
    const char* lable = "|/-\\";
    int len = strlen(lable);
    static int cnt = 0;

    int num = (int)(cur*100/total);
    int i = 0;
    for(;i < num;i++)
    {
        buffer[i] = STYLE;
    }
    double rate = cur/total;
    cnt %= len;
    printf("[%-100s][%.1f%%][%c]\r",buffer,rate*100,lable[cnt]);
    cnt++;
    fflush(stdout);
}

总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

相关推荐
Moshow郑锴3 小时前
Ubuntu 26.04 更换阿里云源镜像
linux·运维·ubuntu
Jason_chen3 小时前
Linux 6.2 串口机制深度解析:AI驱动的自适应通信与零信任串口安全架构
linux
茉莉玫瑰花茶4 小时前
综合案例 - AI 智能租房助手 [ 5 ]
服务器·数据库·人工智能·python·ai
ShineWinsu4 小时前
对于Linux:线程概念与分页存储管理的解析
linux·运维·服务器·面试·线程·进程·虚拟空间地址
用户3946235365244 小时前
Uboot - DM框架
linux
x***r1515 小时前
.NET 10 SDK 安装教程(dotnet-sdk-10.0.100-win-x64详细步骤)
java·服务器·前端
鹤落晴春5 小时前
RH124问答5:管理本地用户和组
linux·运维·服务器
其实防守也摸鱼6 小时前
软件安全与漏洞--Windows底层原理与软件逆向工程基础
linux·网络·数据库·算法·安全·安全架构·软件安全与漏洞
云栖梦泽6 小时前
Linux内核与驱动:pinctl子系统和GPIO子系统
linux·单片机·嵌入式硬件