0


【Linux学习】(8)第一个Linux编程进度条程序|git三板斧

前言

  1. 第一个Linux编程——进度条
  2. git的简单使用

一、第一个Linux编程——进度条

在写进度条之前我们需要两个基础知识:

  1. 回车换行
  2. 缓冲区

1. 回车换行

  • 首先我们需要知道回车换行它是两个概念,回车是回车,换行是换行
  • 换行:光标从上往下,直接到下一行(例如光标现在在当前行的第5个位置,换行之后光标直接挪到下一行的第5个位置,并没有在下一行的最左侧) 回车:把光标挪到当前行的最开始(最左侧),还在当前行
  • 换行一般不单独使用,一般换行回车一起用,所以在C语言中用\n表示换行(注意:\n是换行+回车)
  • 回车,我们用转义字符\r表示

2. 行缓冲区

(1)引入行缓冲区

在讲解之间我们先来学习一个系统函数——sleep

  • 我们通过man手册,查看sleep的使用在这里插入图片描述
  • 调用sleep,休眠指定的秒数

现在我们来看下面的两个代码:

两段代码唯一的区别就是代码1打印完之后换行,代码2打印完之后不换行,如下图:

在这里插入图片描述
分别编译运行这两段代码,运行结果是怎么样的呢?

  • 代码1:先打印hello linux!和换行,随后休眠2秒,结束运行
  • 代码2:先休眠2秒,随后打印hello linux!,结束运行

问题:我们学过C语言的都知道,C代码一定是按照顺序从上往下执行的,无论是代码1还是代码2都应该是先执行A处再执行B处,但是为什么代码2的运行效果好像是先执行了B处的代码,随后才执行的A处?

从C语言的执行顺序,我们知道一定是先执行printf,随后再执行sleep

在sleep的时候,printf已经执行了,只不过信息没有打印出来

那在我sleep的时候,信息“hello linux!”在哪里?——他一定是被保存起来了!——保存在缓冲区

缓冲区就是由C语言维护的一段内存!

缓冲区的刷新策略:行刷新

  • 行刷新:缓冲区他要看你输出的字符串是不是一个完整行- 如果是一个完整行,缓冲区就立刻将存在缓冲区的内容刷新出来- 如果不是一个完整行,缓冲区就不刷新,直到程序退出或者遇到换行符才将存在缓冲区的内容刷新出来- 完整行的标准:是否有‘\n’换行符

了解了缓冲区和缓冲区的刷新策略,现在我们就知道为什么代码2会先休眠再输出了,因为代码2没有‘\n’换行符,不是一个完整行,所以直到程序退出才从缓冲区刷新出来

(2)怎样强制刷新缓冲区

我们先来认识两个知识点:

  1. C程序默认会帮我们打开三个输入输出流,分别叫做标准输入、标准输出、标准错误。今天我们只考虑标准输出。C语言默认会帮我们打开三个输入输出文件,输出文件就是显示器,显示器文件对应C语言的stdout。
#include<stdio.h>extern FILE *stdin;extern FILE *stdout;extern FILE *stderr;
  1. 使用fflush刷新文件流,即使缓冲区不是一个完整行,也可以使用fflush强制将缓冲区中的内容马上刷新出来在这里插入图片描述

(3)倒计时

在实现进度条之前,我们可以先来实现一个简易的倒计时程序。

实现倒计时需要注意以下几个问题:

  1. 倒计时需要将之前的数字覆盖掉 - 光标不能向后移动——》解决方案:回车‘\r’- 光标不能换行且要立马将缓冲区数据刷新出来——》fflush
  2. 不想让最后的结果被bash覆盖——》在程序的最后换行
  3. 从大到小倒计时,随着倒计时的运行会导致不能完全覆盖之前的数字,例如9覆盖10,反而变成90——》-numd%:左对齐num个字符
#include<stdio.h>#include<unistd.h>intmain(){int cnt =10;while(cnt >=0){printf("%-2d\r", cnt);fflush(stdout);sleep(1);
        cnt--;}printf("\n");//printf("hello linux!"); //A//fflush(stdout);         //强制刷新文件流,将缓冲区中的内容马上刷新出来//  sleep(2);                //Breturn0;}

3. 进度条

(1)准备工作

  1. 首先mkdir processbar创建processbar目录,用于保存进度条代码
  2. 在processbar目录下,touch processbar.c processbar.h main.c三个文件,分别用于进度条的实现、进度条的声明、进度条的调用
  3. 再touch Makefile,用于项目的自动化构建

(2)实现简单的进度条样式

  • 编写Makefile文件,通过make命令生成可执行程序和清理项目
processbar:processBar.c main.c # 可执行目标文件依赖多个源文件的话,使用空格分隔即可
    gcc $^ -o $@

.PHONY:clean
clean:
    rm -f processbar
  • processbar.h:进度条声明
//防止头文件被重复包含#pragmaonce//声明常用的头文件#include<stdio.h>#include<string.h>#include<unistd.h>//声明函数externvoidprocessbar(int speed);//进度条的长度是一个常量,所以我们将其定义为一个宏#defineNUM101//进度条长度为100,但因为C字符串以'\0'结尾,所以将其定义为101//进度条的主体字符格式也是一个常量,所以我们也将其定义为一个宏#defineBODY'='//进度条推进是右边有一个字符'>'表示在推进#defineRIGHT'>'
  • processbar.c:进度条样式的实现

1、如何实现进度条推进的效果

答:循环——通过每一次多输出一个字符,并将前一次输出的字符覆盖,这样不断循环,从左向右依次增加,实现进度条推进的效果

2、进度条的样式

  • 预留100的长度,并左对齐——%-100s
  • 显示进度条推进的进度,即百分比(注意‘%’是一个特殊字符,一般通过两个‘%%’才能输出)
  • 进度条工作时字符’|'顺时针旋转表示在工作
#include"processBar.h"//进度条工作时字符'|'顺时针旋转表示在工作constchar* lable ="|/-\\";//'\'是特殊字符//实现进度条推进的样式,参数speed—由调用者决定每一次推进的速度voidprocessbar(int speed){//定义进度条char bar[NUM];//初始化进度条memset(bar,'\0',sizeof(bar));int len =strlen(lable);//循环:通过每一次多输出一个字符,并将前一次输出的字符覆盖,这样不断循环实现进度条推进的效果//进度条长度为NUM-1,从长度为0开始循环,需要循环NUM次—》[0,NUM-1]int cnt =0;//计数器while(cnt <= NUM -1){//这里我们不使用'\n',使用'\r'回车将前一次的进度条覆盖掉printf("[%-100s][%d%%][%c]\r", bar, cnt, lable[cnt%len]);//没有'\n',缓冲区就没有立即刷新,因为显示器默认行刷新//所以这里我们使用fflush函数立马把缓冲区的内容刷新出来fflush(stdout);//每一次输出休眠0.1秒——usleepusleep(speed);//迭代:每一次比上一次多一个字符
         bar[cnt++]= BODY;//注意:临界情况,即当cnt=NUM-1时就不能再执行了if(cnt < NUM -1){
            bar[cnt]= RIGHT;}}//进度条打印完之后,为了不让bash命令行把我们的进度条覆盖掉,所以这里换行printf("\n");}
  • main.c:进度条样式的调用(测试)
#include"processBar.h"intmain(){//每一次推进,休眠0.1秒processbar(100000);return0;}

(3)进度条调用的场景

  1. 在实际中进度条的进度不应该有我们循环模拟实现,而是由调用者决定的
  2. 在实际中进度条调用时,调用者进行着某种下载任务,每下载1%就调用进度条打印一次进度,不断重复下载,直到下载任务完成
  • processbar.c:进度条样式的实现
//进度条工作时字符'|'顺时针旋转表示在工作constchar* lable ="|/-\\";//'\'是特殊字符//定义进度条char bar[NUM];//参数rate为进度条的进度//processbar每一次调用进度+1voidprocessbar(int rate){//当进度条小于0和大于100时,直接退出if(rate <0|| rate >100)return;int len =strlen(lable);printf("[%-100s][%d%%][%c]\r", bar, rate, lable[rate%len]);fflush(stdout);
    bar[rate++]= BODY;//注意:临界情况,即当rate=NUM-1时就不能再执行了if(rate < NUM -1) bar[rate]= RIGHT;}//下载完毕之后调用initbar初始化进度条voidinitbar(){memset(bar,'\0',sizeof(bar));}
  • main.c:进度条样式的调用(测试)
#include"processBar.h"typedefvoid(*callback_t)(int);//函数指针类型//模拟一种安装或下载voiddownLoad(callback_t cb){int total =1000;//需要下载1000MBint curr =0;//一开始还没下载为0MB//当curr>total即下载完成while(curr <= total){//进行某种下载任务usleep(10000);//模拟下载的时间int rate = curr*100/total;//更新进度cb(rate);//通过回调,展示进度
        curr +=10;//迭代:循环一次下载10M}printf("\n");}intmain(){downLoad(processbar);initbar();downLoad(processbar);initbar();downLoad(processbar);initbar();downLoad(processbar);initbar();return0;}

二、简单使用git

1. git是什么

  1. git是一个版本控制器
  2. git的核心工作主要是两个: - 使用git来进行版本管理- 使用git多人协作开发
  3. git是client和Server一体的(例如:本地仓库可以传到远端,远端仓库也可以拉取到本地)
  4. git是一个开源的软件,基于git搞了一些商业版的网站——github&&gitee
  • 理解什么是版本管理?

例如:在写毕业论文的时候,我们需要不断的修改,在修改的时候就会产生不同的版本,这个时候我们需要将其保存在同一个文件夹下,也可将这个文件夹称作仓库。这个仓库就是做毕业论文的版本管理的!

  • 理解git

我们怕电脑中的本地仓库被我们弄丢,所以我们可以将其传到远程仓库git中!

2. git的简单使用

在这里我们只学习git的简单使用,把本地仓库的代码传上远端仓库即可

(1)新建仓库

在菜单栏右侧有一个‘+’,新建仓库:

在这里插入图片描述

现阶段我们创建的仓库,填写好仓库名和仓库介绍即可

在这里插入图片描述

  • tip:.gitignore文件是筛选从本地上传到远端仓库的文件的,只要在.gitignore文件有的文件就不能上传到远端仓库!在这里插入图片描述

(2)将远端仓库拉取到本地

  • 先将仓库的url复制一份:在这里插入图片描述在这里插入图片描述
  • 将远端仓库拉取到本地:

注意:在拉取之前先检测Linux是否下载了git

git --help#检测git是否安装好,简写为--h也可以git --version#也可检查是否安装好

出现如下图所示,即安装好了

在这里插入图片描述
如果没有安装,粘贴如下命令安装:

sudo yum installgit

将远端仓库拉取到本地,指令如下:

git clone [url]#这里的url就是刚在远端仓库复制的url

在这里插入图片描述

(3)本地仓库

  • 我们需要把本地仓库的代码上传到远端仓库,那本地仓库在哪里呢?

本地仓库 .git 在我们拉取到本地的目录中,注意它隐藏的

在这里插入图片描述

  • 为什么我们的本地仓库是隐藏的——就是因为它不想让我们对其修改

(4)三板斧第一招:git add

  • 先把我们要上传的文件拷贝到刚才拉取的克隆本地当中在这里插入图片描述
  • 注意:这个文件虽然拷贝到了本地当中,但是它还没有被仓库管理起来
  • 所以git add第一板斧将新拷贝到本地的文件添加到本地仓库
gitadd[文件名]

在这里插入图片描述

(5)三板斧第二招:git commit

  • 其实git add只是将其添加到仓库的暂存区里了,还需要git commit第二板斧将其真正提交到本地仓库中!
  • git commit提交的时候还应该注明提交日志,描述改动的详细内容
  • 注意:提交日志不能乱写,它是给我们查看的——即通过日志了解提交的文件具体做了什么事
git commit -m "提交日志信息"
  • 首次使用git commit的时候,可能会报错,因为Git需要知道你的用户名和电子邮件地址,以便在每次提交时记录这些信息,但你还没有设置全局的用户名和邮箱。(其本质是为了对代码进行溯源)在这里插入图片描述
  • 完成设置后,你应该能够成功地进行Git提交了。再次尝试运行你的提交命令在这里插入图片描述 tip:如果这里设置的邮箱与你git上的邮箱不一致,可能会导致在Gitee没有提交的小绿点。

(6)三板斧第三招:git push

  • 将本地仓库同步到远端仓库(即远端服务器)上
git push
  • push时需要填写用户名和密码在这里插入图片描述
  • 同步成功后,刷新Gitee就可以看到你提交的文件了在这里插入图片描述

(7)补充:git log&&git status

  • git log:查看历史提交记录在这里插入图片描述
  • git status:查看提交状态在这里插入图片描述 到这里我们就学完了git的基本使用
标签: linux 学习 git

本文转载自: https://blog.csdn.net/wangjiushun/article/details/141901109
版权归原作者 从前慢,现在也慢 所有, 如有侵权,请联系我们删除。

“【Linux学习】(8)第一个Linux编程进度条程序|git三板斧”的评论:

还没有评论