Linux 倒计时与进度条程序实现及 Plus 升级版本
前言
本文讲解倒计时小程序、进度条小程序及其 Plus 升级版本的实现。
Linux C 语言实现倒计时和进度条程序。利用 \r 实现光标回退,fflush 强制刷新缓冲区,sleep/usleep 控制时间间隔。包含基础版与使用回调函数的升级版,配合 Makefile 进行自动化构建。

本文讲解倒计时小程序、进度条小程序及其 Plus 升级版本的实现。
键盘上的 Enter 键作用是回车并换行。回车是指让当前光标移动至当前行的起始位置,换行是换到下一行径直向下的对应位置。
在 Linux 中使用 \r 表示回车,使用 \n 表示换行。
使用 gcc 编译链接为可执行程序后运行,C 语言程序从上往下执行。调用 printf 打印的字符串去哪了呢?
示例代码:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("hello");
sleep(2);
return 0;
}
sleep 函数休眠指定秒数,头文件为 #include <unistd.h>。
2 秒后 hello 被打印在屏幕上。说明字符串被保存起来了,这个保存位置叫做缓冲区。缓冲区由 C 语言维护的一段内存组成,当程序结束或遇到 \n 时会刷新缓冲区内容。
可以使用 fflush 函数强制刷新缓冲区内容,需要传入对应的流(标准输入 stdin,标准输出 stdout,标准错误 stderr)。将 hello 刷新输出到屏幕,需传入标准输出流 stdout。
修改代码调用 fflush 强制刷新缓冲区即可:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("hello");
fflush(stdout);
sleep(2);
return 0;
}
#include <unistd.h>。%2d 占两个字符,默认右对齐。改为左对齐 %-2d 符合阅读习惯。#include <stdio.h>
#include <unistd.h>
int main() {
int cnt = 10;
while (cnt >= 0) {
printf("%-2d\r", cnt);
fflush(stdout);
cnt--;
sleep(1);
}
printf("\n");
return 0;
}
进度条英文为 progressbar。建立 progressBar.c 编写进度条函数实现,main.c 编写主逻辑,progressBar.h 编写头文件和声明。创建 makefile 用于自动化构建。
根据 make/makefile 配置重点进行讲解。
progressBar: main.c progressBar.c
gcc $^ -o $
.PHONY: clean
clean:
rm -f progressBar
#pragma once 防止头文件重复展开。#include <string.h>,usleep 头文件 #include <unistd.h>。usleep 单位为微秒,1 秒=1000000 微秒。#pragma once
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define BODY '-'
#define RIGHT '>'
extern void progressBar(int speed);
#include "progressBar.h"
int main() {
progressBar(50000);
return 0;
}
[ ] 分隔功能:进度条、百分比、加载旋转字符。\0。|/-\\,使用 strlen 求长度 len,通过 cnt % len 索引。\n,使用 fflush 强制刷新。printf 中 % 需写为 %%,\r 放在最后以对齐。#include "progressBar.h"
const char* lable = "|/-\\";
void progressBar(int speed) {
char str[102];
memset(str, '\0', sizeof(str));
int len = strlen(lable);
int cnt = 0;
while (cnt <= 100) {
printf("[%-100s][%d%%][%c]\r", str, cnt, lable[cnt % len]);
fflush(stdout);
str[cnt++] = BODY;
if (cnt < 100) {
str[cnt] = RIGHT;
}
usleep(speed);
}
printf("\n");
}
此版本接收从 0 到 100 的参数,直接给出对应进度条状态,将休眠和循环设计交给用户完成。支持回调函数特性,适用于模拟下载场景。连续多次下载时需提前清空字符数组。
progressBar: main.c progressBar.c
gcc $^ -o $
.PHONY: clean
clean:
rm -f progressBar
#pragma once
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define BODY '-'
#define RIGHT '>'
extern void progressBar(int cnt);
extern void initbar(char* str, int sz);
char str[102];
#include "progressBar.h"
typedef void (*callback_t)(int);
void downLoad(callback_t cb) {
int total = 1000;
int cur = 0;
while (cur <= total) {
int rate = cur * 100 / total;
cb(rate);
usleep(50000);
cur += 10;
}
printf("\n");
}
int main() {
printf("downLoad\n");
initbar(str, sizeof(str));
downLoad(progressBar);
printf("downLoad\n");
initbar(str, sizeof(str));
downLoad(progressBar);
printf("downLoad\n");
initbar(str, sizeof(str));
downLoad(progressBar);
return 0;
}
#include "progressBar.h"
const char* lable = "|/-\\";
void progressBar(int cnt) {
if (cnt < 0 || cnt > 100) {
return;
}
int len = strlen(lable);
printf("[%-100s][%d%%][%c]\r", str, cnt, lable[cnt % len]);
fflush(stdout);
str[cnt++] = BODY;
if (cnt < 100) {
str[cnt] = RIGHT;
}
}
void initbar(char* str, int sz) {
memset(str, '\0', sz);
}
以上就是倒计时与进度条程序的实现内容,希望对读者朋友们有帮助。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online