方案
<?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;
}