Linux进度条小程序(结合缓冲区相关知识)

Posted DR5200

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux进度条小程序(结合缓冲区相关知识)相关的知识,希望对你有一定的参考价值。

文章目录

一.行缓冲

#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()

        printf("hello world!\\n");
        sleep(5);

#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()

        printf("hello world!");
        sleep(5);

在写我们的进度条之前,先讲一些补充知识,首先我们来看下面这两段代码,可以发现两段代码唯一的区别就是printf末尾加没加 \\n ,可能很多同学认为这两段代码运行结果是一样的,但实际上运行之后我们可以看到第一段代码先打印出 hello world 再 sleep 5秒,第二段代码先 sleep 5 秒,再打印出 hello world

这是怎么回事呢? 莫非第二段代码 printf 和 sleep 的执行顺序变了? 当然不是,我们的代码肯定是从上到下依次执行的,printf 一定是先于 sleep 执行的, 真正的原因是 hello world 被缓存起来,并没有立即被刷新到显示器,当 sleep 5秒后,缓冲区的内容才被刷新出来,下面介绍一下缓冲区的分类

缓冲区的分类

全缓冲:我们缓存在缓冲区的东西在缓冲区满的时候,才写入磁盘或者我们调用fflush刷新缓冲区才能写入到磁盘。对于全缓冲,如果我们缓冲区没满,或者我们没有手动刷新缓存,那么缓存区的内容是不能写入到磁盘的。(对文件写入时采用全缓冲)

行缓冲:我们标准输入、标准输出都是采用的行缓存,也就是遇到换行符的时候,才会将缓存区的东西写入到磁盘。

无缓存:有的时候,我们希望一些内容在第一时间写入磁盘或者显示出来,比如我们显示错误信息的时候,这时候典型的例子比如标准出错,它就是直接显示出错信息,而不会先放入缓存。

通常情况下,我们需要知道的是,在缓冲区满、手动调用fflush、或者程序结束的时候,我们的缓冲区才会得到刷新,并写入磁盘。

由此,我们就可以知道原因了,hello world 按照行缓冲的方式缓存到缓冲区,遇到换行符才会被刷新到显示器上,所以第一段代码缓冲区里是 hello world\\n,遇到换行符被刷新出来,第二段代码缓冲区里是 hello world,没有遇到换行符,直到程序结束,缓冲区的内容才被刷新出来

(1). 这个缓冲区在哪里 ?
(2). 这个缓冲区是谁提供的?
(3). OS也是有缓冲的 vs 文件缓冲

#include<stdio.h>
#include<unistd.h>
int main()

        printf("hello printf\\n");
        fprintf(stdout,"hello fprintf\\n");

        const char* buf = "hello write\\n";
        write(1,buf,strlen(buf));

        fork();
        return 0;
                    

这段代码我们 ./myproc 运行起来,结果如我们所想,但如果重定向到一个文件当中,结果就不如我们所想了

二.\\n和\\r

换到下一行 : 换行(\\n)
回到一行的开始 : 回车(\\r)

在C/C++中,\\n 表示的有两个意思 : 回车 + 换行

我们平常键盘上的Enter键就是回车 + 换行的功能,这也是为什么Enter键上的图标是一弯箭头,表示换到下一行并回到下一行的开始

结合以上的知识,我们可以先写出一个简易的倒计时程序

#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()

        int i = 10;
        while(i)
        
                printf("%2d\\r",i);
                // 刷新缓冲区
                fflush(stdout);
                sleep(1);
                i--;
        

三.进度条实现

#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()

        int i = 0;
        char proc[102];
        memset(proc,'\\0',sizeof proc);
        const char* lable = "|/-\\\\";
        while(i <= 100)
        
                printf("[%-100s][%d%%][%c]\\r",proc,i,lable[i % 4]);
                // 刷新缓冲区
                fflush(stdout);
                proc[i] = '#';
                usleep(100000);
                i++;
        
        printf("\\n");

以上是关于Linux进度条小程序(结合缓冲区相关知识)的主要内容,如果未能解决你的问题,请参考以下文章

Linux下的进度条小程序

Linux | 手把手教你写一个进度条小程序

C语言实现windows,linux双版本下的进度条小程序,快来试一试吧

<Linux>进度条小程序和git使用详解

Linux下实现进度条小程序

Linux下的进度条小程序