天天看點

在終端實作下載下傳進度條方案解釋說明C

方案

<?php
// 參考https://mengkang.net/1412.html
$width = exec("tput cols");

$progress = "[]100%";
$del = strlen($progress);
$width = $width - $del;

$progress = "[%-{$width}s]%d%%\r";
for($i=1;$i<=$width;$i++){
    printf($progress,str_repeat("=",$i),($i/$width)*100);
    usleep(30000);
}

echo "\n";           

解釋說明

  • tput cols

    擷取終端的“寬度”,實際是字元列數;
  • %s

    我們知道是字元串的占位符;
  • %-{n}s

    的意思是占位

    n

    個字元,不足的用空格補充,這樣在輸出進度條的時候,最末尾的值的位置就是固定的;
  • %%

    輸出百分号;
  • 最重要的一點,格式的末尾使用了

    \r

    則将光标移動到行首,則下次再輸出時則把上次的整行覆寫,給人進度條動态變化的效果。

C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <unistd.h>

int main()
{
    struct winsize size;
    ioctl(STDIN_FILENO, TIOCGWINSZ, &size);
    int width = size.ws_col;

    const char *progress = "[]100%";
    width = width - strlen(progress);

    char width_str[10] = {0};
    sprintf(width_str,"%d",width);

    char progress_format[20] = {0};

    strcat(progress_format,"[%-");
    strcat(progress_format,width_str);
    strcat(progress_format,"s]%d%%\r");

    // printf("%s\n",progress_format);
    // [%-92s]%d%%\r

    char progress_bar[width+1];
    memset(progress_bar,0,width+1);

    for(int i=1;i<=width;i++){
        strcat(progress_bar,"=");
        printf(progress_format,progress_bar,(i*100/width));
        // 或者使用
        // fprintf(stdout,progress_format,progress_bar,(i*100/width));
        fflush(stdout); // 必須重新整理緩存區,否則會顯得很卡頓
        usleep(10000);
    }

    printf("\n");
    return 0;
}