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提供了大量能使我们快速便捷地处理数据的函数和方法。

相关推荐
三8442 小时前
文件查找/文件压缩/解压缩
linux·运维·服务器
小猪写代码2 小时前
Linux 管道(Pipeline)作业
linux·运维·服务器
桌面运维家3 小时前
如何用半缓存云桌面将服务器硬盘容量扩展至本地终端?
运维·服务器·缓存
Jurio.3 小时前
Codex App SSH 远程开发教程:本地连接远程服务器项目
服务器·ssh·远程工作·codex
会周易的程序员5 小时前
microLog 的本地日志读取接口 log_reader — 本地日志文件读取工具开发指南
linux·物联网·架构·嵌入式·日志·iot·aiot
yoothey5 小时前
报废审批流规则引擎设计——责任链模式完整实现
linux·开发语言·bash
2501_925963385 小时前
外设的常见问题
linux
l1t5 小时前
在linux和windows中解决duckdb 1.6dev版本输出执行计划报错问题
linux·运维·数据库·windows·duckdb
tryCbest6 小时前
Python 文件操作
服务器·python
柳鲲鹏6 小时前
LINUX高通平台交叉编译地图软件GDAL
linux