Linux小程序
在Linux中我们实现两个小程序来体会\r和\n的区别,以及缓冲区是什么?
前言
回车和换行的区别
对于 \r 和 \n 的理解:
- \n 表示换行且回到下一行的最开始的位置
- \r 表示的是回车,即将光标回到当前行最开始的位置
在C语言中,我们单单使用“\n”就可以实现换行回车,但是”\r“只能表示回车
//在定义中\n表示的是换行符号,只是在语言实现中,包含了自动回车这一功能,最后导致,\n为换行回车 #include<stdio.h> void Func1() { printf("hello world\n"); printf("换行+回车\n"); //hello world return; //换行+回车 } void Func2() { printf("123456\r"); printf("654\n"); //测试结果为654456 return; } int main() { printf("测试换行\n"); Func1(); printf("测试回车\n"); Func2(); return 0; }
缓冲区
Linux缓冲区是指在内存中开辟的一块区域,用于存储输入输出数据的临时存储区域。当应用程序向文件或设备进行读写操作时,数据会先被存储到缓冲区中,然后再由缓冲区将数据写入磁盘或设备中。缓冲区的作用是提高数据读写的效率,减少磁盘或设备的访问次数,从而提高系统的性能。在Linux系统中,缓冲区的大小可以通过修改内核参数来进行调整。
我们来看看缓冲区的体现
认识fflush函数
fflush(stdin)是清空输入缓存的函数,在输入字符之前调用它可以清除之前未读取的字符。
fflush(stdout)是刷新输出缓冲区的函数,它可以强制将缓冲区中的输出立即发送到输出设备(通常是显示器)。它对应的头文件是
#include<stdio.h> #include<unistd.h> //sleep的头文件 int main() { printf("hello world!") fflush(stdout); //刷新缓冲区 sleep(2); return 0; }
总结
- \n 自带刷新缓冲区的功能
- fflush(stdout)可以强制刷新输出缓冲区的函数
小程序的实现
我们学习了上文中的换行和回车,以及缓冲区的概念,以此尝试在Linux中尝试做两个小程序,倒计时和进度条程序的实现。
倒计时程序
结合换行和回车,以及缓冲区的概念,我们可以实现倒计时
# include<stdio.h> # include<unistd.h> void Fun1(int n) { //实现倒计时的函数 int i=n; for(; i >= 0 ; i-- ) { printf("%-5d\r",i); fflush(stdout); sleep(1); } } int main() { //实现倒计时,我们测试过缓冲区和换行回车 //倒计时的实现应该是使用 \r 回车符号,不断变更数值 int n=0; printf("请输入N的数值:"); scanf("%d",&n);// 实现任意倒计时 //实现函数主体 Fun1(n); return 0; }
进度条程序
进度条是指通过展示下载的过程(进度)以及百分比还有加载光标,来模拟进度条。
Progressbar.h
进度条头文件,我们在里面声明函数,宏定义变量,导入头文件。
//下面是Progressbar.h文件内容 # pragma once #include<stdio.h> #include<unistd.h> //进度条的头文件,进行设置宏定义 #define Num 102 #define Top 100 #define Body '=' #define Right '>' //声明函数 extern void progressbar(int speed);//实现 extern void initbar(); //初始化
Progressbar.c
//实现进度条程序的主要文件 #include<stdio.h> #include "ProgressBar.h" #include<string.h> #include<unistd.h> //方案二: const char* lable="\\|/-"; char bar[Num]; #define GREEN "\033[0;32;32m" //这是改变打印的颜色语句 #define NONE "\033[m" void progressbar(int rate) //rate表示的是当前的进下载进度 0-100区间的范围 { //rate 表示的是当前下载进度 if(rate<0||rate>100 ) return ; int len=strlen(lable); printf(GREEN"[%-100s]"NONE"[%d%%][%c]\r",bar,rate,lable[rate%len]); fflush(stdout); //使用fflush强制刷新输出缓冲区 bar[rate++]=Body; if(rate<100) bar[rate]=Right; //只要没有超过100 就加上Right } void initbar() { memset(bar,'\0',sizeof(bar)); } //下面是第一种方法,直接调用progressbar(加载速度) 传参为speed 即文件下载速度 //方案一: //void progressbar(int speed) //{ // //实现进度条代码 // char bar[Num]; // //初始化bar // memset(bar, '\0', sizeof(bar)); // // //使用while循环实现 // int len = strlen(lable); // int count = 0; // while (count <= 100) // { // //进行打印 // printf("[%-100s][%d%%][%c]\r", bar, count, lable[count % len]); // fflush(stdout); //没有\n,就无法刷新,只能手动刷新,使用fflush,显示器默认的是行刷新 // bar[count++] = Body; // if (count < 100) bar[count] = Right; // usleep(speed); // } // printf("\n"); //}
test.c
这是主要文件,从该文件传参实现文件的运行
#include<stdio.h> #include"ProgressBar.h" typedef void (*callback_t)(int);// 函数指针类型 void downLoad(callback_t cb) //使用函数指针来调用 { //callbak_t 实际上就是表示一个参数为int的函数指针,那么cb表示这个函数名 int total =1000; //下载的总容量 int curr=0; //当前下载的容量 while(curr<=total) { usleep(50000); //表示模拟下载花费的时间 int rate=curr*100/total; //更新进度 cb(rate);//将rate参数传递给cb函数(形参) curr+=10;//表示一次循环下载了一部分 } printf("\n"); } int main() { printf("下载1:\n"); downLoad(progressbar); initbar(); //进行对于bar初始化 printf("下载2:\n"); downLoad(progressbar); initbar(); //下载一次就要进行初始化 printf("下载3:\n"); downLoad(progressbar); initbar(); printf("下载4:\n"); downLoad(progressbar); initbar(); return 0; } //方案一: 手动控制每一次加载usleep的时间 //int main() //{ // //实现进度条的主程序 // printf("第一次加载:\n"); // // progressbar(100000); // // return 0; //}
总结
- \n和\r我们都进行了解释和演示,对于缓冲区的概念图文解释,认识到了两种方式来强制刷新缓冲区。
- 标准输入(stdin)标准输出(stdout)标准错误 ,我们认识到了fflush函数来强制刷新
- \n 实际上是执行换行+回车操作的,也有刷新缓冲区的作业
- 我们实现了两个Linux上的小程序,倒计时以及进度条。