【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>int main()
{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);                //Breturn 0;
}

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:进度条声明
//防止头文件被重复包含
#pragma once//声明常用的头文件
#include<stdio.h>
#include<string.h>
#include<unistd.h>
//声明函数
extern void processbar(int speed);
//进度条的长度是一个常量,所以我们将其定义为一个宏
#define NUM 101//进度条长度为100,但因为C字符串以'\0'结尾,所以将其定义为101
//进度条的主体字符格式也是一个常量,所以我们也将其定义为一个宏
#define BODY '='
//进度条推进是右边有一个字符'>'表示在推进
#define RIGHT '>'
  • processbar.c:进度条样式的实现

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

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

2、进度条的样式

  • 预留100的长度,并左对齐——%-100s
  • 显示进度条推进的进度,即百分比(注意‘%’是一个特殊字符,一般通过两个‘%%’才能输出)
  • 进度条工作时字符’|'顺时针旋转表示在工作
#include"processBar.h"//进度条工作时字符'|'顺时针旋转表示在工作
const char* lable = "|/-\\"; //'\'是特殊字符
//实现进度条推进的样式,参数speed—由调用者决定每一次推进的速度
void processbar(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"int main()
{//每一次推进,休眠0.1秒processbar(100000);return 0;
}

(3)进度条调用的场景

  1. 在实际中进度条的进度不应该有我们循环模拟实现,而是由调用者决定的
  2. 在实际中进度条调用时,调用者进行着某种下载任务,每下载1%就调用进度条打印一次进度,不断重复下载,直到下载任务完成
  • processbar.c:进度条样式的实现
//进度条工作时字符'|'顺时针旋转表示在工作
const char* lable = "|/-\\"; //'\'是特殊字符
//定义进度条
char bar[NUM];
//参数rate为进度条的进度
//processbar每一次调用进度+1
void processbar(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初始化进度条
void initbar()
{memset(bar,'\0',sizeof(bar));
}
  • main.c:进度条样式的调用(测试)
#include"processBar.h"typedef void (*callback_t)(int);//函数指针类型
//模拟一种安装或下载
void downLoad(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");
}
int main()
{downLoad(processbar);initbar();downLoad(processbar);initbar();downLoad(processbar);initbar();downLoad(processbar);initbar();return 0;
}

二、简单使用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 install git

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

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

在这里插入图片描述

(3)本地仓库

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

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

在这里插入图片描述

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

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

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

在这里插入图片描述

(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的基本使用

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

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

相关文章

DEVOPS: 认证与调度

概述 不知道大家有没有意识到一个现实&#xff0c;就是大部分时候&#xff0c;我们已经不像以前一样通过命令行&#xff0c;或者可视窗口来使用一个系统了现在我们上微博、或者网购&#xff0c;操作的其实不是眼前这台设备&#xff0c;而是一个又一个集群 通常&#xff0c;这样…

MUX VLAN 实验配置

MUX VLAN&#xff08;Multiplex VLAN&#xff09;是一种高级的VLAN技术&#xff0c;通过在交换机上实现二层流量隔离和灵活的网络资源控制&#xff0c;提供了一种更为细致的网络管理方式 MUX VLAN通过定义主VLAN&#xff08;Principal VLAN&#xff09;和多个子VLAN&#xff0…

海外云手机怎样助力亚马逊店铺运营?

随着全球化的发展&#xff0c;越来越多的企业开始重视海外市场的拓展&#xff0c;尤其是出海企业和B2B外贸企业。亚马逊作为全球最大的电商平台之一&#xff0c;成为了许多企业争夺国际市场的重点战场。本文将深入分析海外云手机在优化亚马逊店铺引流中的作用和优势&#xff0c…

优惠券项目的设计与实现,完结!

你好 我是田哥 我的充电桩项目中&#xff0c;优惠券相关功能已基本完成。另外&#xff0c;关于充电桩项目&#xff0c;我之前分享过一些相关文章&#xff1a; 充电桩项目&#xff0c;开源啦&#xff01; 充电桩项目实战&#xff1a;消息丢失和重复消费问题 用充电桩项目面试&am…

【electron8】electron实现“图片”的另存为

注&#xff1a;该列出的代码&#xff0c;都在文章内示例出 1. 另存为按钮事件&#xff1a; const saveAsHandler async () > {const { path, sessionId } recordInfoif(typeof message ! string) return;// 因为我的图片是加密的&#xff0c;所以我需要根据接口返回的路…

使用vue+kkFileview组件实现各种类型文件预览

关于kkFileView 【参考】&#xff1a;https://kkfileview.keking.cn/zh-cn/docs/home.html 文档在线预览项目解决方案&#xff0c;项目使用流行的spring boot搭建&#xff0c;易上手和部署。万能的文件预览开源项目&#xff0c;基本支持主流文档格式预览 本项目介绍 项目使用…

低空经济产业链、政策、延伸品调研笔记

文章目录 1 低空经济市场1.1 政策摘要1.2 市场规模预测 3 涉及产业链与核心产品3.1 产业链3.2 原材料3.2.1 上游3.2.2 中游3.2.3下游 3.3 无人机3.4 eVTOL3.5 空管系统 4 应用场景4.1 城市空中出行(UAM)4.2 低空物流4.3 低空旅游与体验4.4 农林植保与监测4.5 基础设施巡检与维护…

JVM基础(内存结构)

文章目录 内存结构JAVA堆方法区 &#xff08;Method Area&#xff09;运行时常量池&#xff08;Runtime Constant Pool&#xff09; 虚拟机栈 &#xff08;Java Virtual Machine Stack&#xff09;本地方法摘栈&#xff08;Native Method Stacks&#xff09;程序计数器&#xf…

Matlab 车牌识别技术

1.1设计内容及要求&#xff1a; 课题研究的主要内容是对数码相机拍摄的车牌&#xff0c;进行基于数字图像处理技术的车牌定位技术和车牌字符分割技术的研究与开发&#xff0c;涉及到图像预处理、车牌定位、倾斜校正、字符分割等方面的知识,总流程图如图1-1所示。 图1-1系统总…

智慧共享空间解决方案是什么

一、智慧共享空间解决方案的定义 智慧共享空间解决方案是一种综合性的策略和技术手段&#xff0c;旨在通过整合智慧技术与共享空间的概念&#xff0c;为公众共同使用的空间提供高效、智能、可持续的运营和管理模式&#xff0c;以满足人们在不同环境下的各种需求&#xff0c;并…

C++基于opencv的视频质量检测--画面冻结检测

文章目录 0.引言1. 原始代码分析2. 优化方案3. 优化后的代码4. 代码详细解读 0.引言 视频质量画面冻结检测已在C基于opencv4的视频质量检测中有所介绍&#xff0c;本文将详细介绍其优化版本。 1. 原始代码分析 图像抖动检测的原始代码&#xff1a; bool ScreenFreezeDetect…

AI驱动的低代码未来:加速应用开发的智能解决方案

引言 随着数字化转型的浪潮席卷全球&#xff0c;企业对快速构建应用程序的需求愈发强烈。然而&#xff0c;传统的软件开发周期冗长、成本高昂&#xff0c;往往无法满足快速变化的市场需求。在此背景下&#xff0c;低代码平台逐渐成为开发者和企业的优选方案&#xff0c;以其“低…

【蓝桥杯选拔赛真题77】python计算小球 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python计算小球 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python计算小球 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

架构师备考-非关系型数据库

基础理论 CAP 理论 C&#xff08;Consistency&#xff09;一致性。一致性是指更新操作成功并返回客户端完成后&#xff0c;所有的节点在同一时间的数据完全一致&#xff0c;与ACID 的 C 完全不同。A &#xff08;Availability&#xff09;可用性。可用性是指服务一直可用&…

内网渗透-初探域渗透

文章目录 环境域信息收集系统基本信息网络信息域控主机信息根据ip查主机名用户信息权限提升网络探针系统命令nbtscanfscannishang 凭据收集 域渗透实战凭据收集(重点)mimikatzProcdumpPwdumpSAMInsidekrbtgt用户hash hash破解解决无法获取明文的问题明文口令传递IPC连接atschta…

windows录屏软件工具推荐!!

如今&#xff0c;科技的进步&#xff0c;互联网的普及&#xff0c;使我们的生活越来越便利&#xff0c;录屏工具的出现&#xff0c;大大提高我们的工作效率。如果你经常需要录制屏幕上的内容&#xff0c;比如制作教学视频、游戏实况记录、演示文稿等等&#xff0c;那这几款软件…

【病毒分析】从无解到破解:Mallox家族linux版本的分析以及解密器的制作

1.背景 Mallox勒索软件首次出现于2021年5月&#xff0c;并在2021年10月扩展到中国市场。截至2024年&#xff0c;它仍然活跃。Mallox通过加密受害者文件并要求支付赎金来恢复数据&#xff0c;使用唯一的加密密钥加密文件&#xff0c;受害者的文件通常会添加“.mallox”或“.mal…

【LeetCode每日一题】——862.和至少为 K 的最短子数组

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 前缀和 二【题目难度】 困难 三【题目编号】 862.和至少为 K 的最短子数组 四【题目描述】 …

容器化核心快速入门

概述 物理机&#xff1a;好比是独立的大船&#xff0c;独立发动机&#xff0c;独立船舱。所有资源共用。运水果的同时就不能运鱼&#xff08; 1964年&#xff09;虚拟机&#xff1a;相当于把大船进行改造&#xff0c;把大船的资源进行独立的拆分&#xff0c;独立的部分都有单独…

适合自己的才行-这五款项目管理软件工具帮你提高管理效能

凭借多年项目管理经验&#xff0c;我试用过数十款国内外项目管理软件。我认为&#xff0c;操作简便性至关重要&#xff0c;因为软件仅是辅助管理工具&#xff0c;复杂性若影响管理本质&#xff0c;则得不偿失。 在生产管理方面&#xff0c;我专注于新产品从立项到研发的全过程…