C语言写一个终端进度条

news2024/7/4 6:23:15

C语言写一个终端进度条

这个功能挺简单的,主要有以下两点:

  • 如何获取终端宽度
  • 如何让字符在原地闪烁

如何获取终端宽度

这里用到了设备控制接口函数ioctl(),下面简单的介绍一下这个函数的用法:

ioctl是一个在Unix和类Unix系统中用于设备驱动程序的设备特定操作的系统调用。它的名称代表“输入/输出控制”,但实际上它可以用于任何设备,不仅仅是输入/输出设备。

在C语言中,ioctl函数的原型如下¹:

#include <sys/ioctl.h>
int ioctl(int fd, int cmd, ...);

这里,fd是一个打开的文件描述符,cmd是设备特定的操作命令,后面的可变参数...取决于cmd指定的操作。

ioctl函数执行成功时返回0,失败则返回-1并设置全局变量errno值。可能的错误包括:

  • EBADF: fd不是一个有效的描述符。
  • EFAULT: argp引用了一个无法访问的内存区域。
  • EINVAL: 请求或argp无效。
  • ENOTTY: fd没有与字符特殊设备关联。
  • ENOTTY: 指定的请求不适用于描述符d引用的对象类型。

更详细的内容可以查询man手册或者其他博客!!这个函数还是挺复杂的!

对于判断终端大小的需求,我们有以下的使用方式:

	struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); // 获取终端大小并且存储到w中
    int barWidth = w.ws_col - 10; // 减去10是为了放置越界

winsize这个结构体位于termios.h头文件内

// /usr/include/asm-generic/termios.h
Struct winsize 
{
    unsigned short ws_row;    /* rows, in character */
    unsigned short ws_col;        /* columns, in characters */
    unsigned short ws_xpixel;    /* horizontal size, pixels (unused) */
    unsigned short ws_ypixel;    /* vertical size, pixels (unused) */
}

使用这个结构体记录窗口终端大小。

如何让字符在原地闪烁

要明白这一点,我们首先要知道两个前置知识:

  • printf的输出条件
  • 终端中的光标

printf的输出条件

没错,printf 也有输出条件,如下:

  • 遇到换行符\n
  • 进程终止
  • 遇到fflush函数

单纯的使用printf并不会直接输出到终端上,会先放在缓冲区,只有遇到换行符才会输出!!!

终端中的光标

我们可以通过'\r'来控制缓冲区中的光标,这样,当我们输出进度条之后,光标又会回到进度条最一开始的位置,这样就可以使得进度条看不见了。

如下:

// 光标置于开头
// progressPercent是进程百分比
printf("\r%3d%% [", progressPercent);

整个函数

// 用法,输入进度值(小数)
// 此函数用于输出一次进度条
void printProgress(float progress) {
        struct winsize w;
        ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
        int barWidth = w.ws_col - 10; // -10 防止越界

        int progressPercent = (int) (progress * 100.0); // 计算出百分值
        printf("\r%3d%% [", progressPercent);
        int pos = barWidth * progress; // 包含隐式类型转换

        for (int i = 1; i < barWidth; ++i) {
                if (i < pos) {
                        printf("#");
                } else {
                        printf(" ");
                }
                fflush(stdout); // 输出完所有内容后刷新缓冲区,代码执行到这里才会有一次输出
        }
        printf("]"); // 最后补上后面的括号
}

这里再写一个main函数用于测试:

int main() {
    for (int i = 0; i <= 100; ++i) {
        printProgress(i / 100.0);
        sleep(1);
    }
    printf("\n");
    return 0;
}

因为作者在项目开发时使用的是自用的通用头文件,代码中并没有包含头文件,请读者自行添加。

执行效果

vscode执行效果:
执行效果1
ssh客户端执行效果:
执行效果2
读者可以给进度条加以改进,作为下层代码,方便在上层代码上调用(例如文件传输C/S)。

:wq 拜拜~~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1643796.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[C语言]指针进阶详解

指针是C语言的精髓所以内容可能会比较多&#xff0c;需要我们认真学习 目录 1、字符指针 2、指针数组 3、数组指针 3.1数组指针的定义 3.2&数组名vs数组名 3.3数组指针的使用 4、数组传参和指针传参 4.1一维数组传参 4.2二维数组传参 4.3一级指针传参 4.4二级指…

如何使用SSH密钥克隆仓库

1.创建SSH Key 在用户目录下查看有没有.ssh目录。如果有且该.ssh目录下有id_rsa&#xff08;私钥&#xff09;&#xff0c;和id_rse_pub(公钥)这俩文件&#xff0c;那么这一步就可以跳过。否则使用以下指令创建SSH Key ssh-keygen -t rsa -C "xxxqq.com" "xx…

【C语言】详解预处理

、 最好的时光&#xff0c;在路上;最好的生活&#xff0c;在别处。独自上路去看看这个世界&#xff0c;你终将与最好的自己相遇。&#x1f493;&#x1f493;&#x1f493; 目录 •✨说在前面 &#x1f34b;预定义符号 &#x1f34b; #define • &#x1f330;1.#define定义常…

解决HTTP 403 Forbidden错误:禁止访问目录索引问题的解决方法

解决HTTP 403 Forbidden错误&#xff1a;禁止访问目录索引问题的解决方法 过去有人曾对我说&#xff0c;“一个人爱上小溪&#xff0c;是因为没有见过大海。”而如今我终于可以说&#xff0c;“我已见过银河&#xff0c;但我仍只爱你一颗星。” 在Web开发和服务器管理中&#x…

3-qt综合实例-贪吃蛇的游戏程序

引言&#xff1a; 如题&#xff0c;本次实践课程主要讲解贪吃蛇游戏程序。 qt贪吃蛇项目内容&#xff1a; 一、功能需求 二、界面设计 各组件使用&#xff1a; 对象名 类 说明 Widget QWidge 主窗体 btnRank QPushButton 排行榜-按钮 groupBox QGroupBox 难…

C/C++开发,opencv-ml库学习,ml模块代码实现研究

目录 一、opencv-ml模块 1.1 ml简介 1.2 StatModel基类及通用函数 1.3 ml模块各算法基本应用 二、ml模块的实现原理 2.1 cv::ml::StatModel的train函数实现原理 2.2 cv::ml::StatModel的predict函数实现原理 2.3 cv::ml::StatModel的save函数和load函数 一、opencv-ml模…

Nginx(搭建高可用集群)

文章目录 1.基本介绍1.在微服务架构中的位置2.配置前提3.主从模式架构图 2.启动主Nginx和两个Tomcat1.启动linux的tomcat2.启动win的tomcat3.启动主Nginx&#xff0c;进入安装目录 ./sbin/nginx -c nginx.conf4.windows访问 http://look.sunxiansheng.cn:7777/search/cal.jsp 3…

力扣 647. 回文子串

题目来源&#xff1a;https://leetcode.cn/problems/palindromic-substrings/description/ C题解1&#xff1a;暴力解法。不断地移动窗口&#xff0c;判断是不是回文串。 class Solution { public:int countSubstrings(string s) {int len s.size();int res 0;for(int i 0;…

【机器学习-21】集成学习---Bagging之随机森林(RF)

【机器学习】集成学习---Bagging之随机森林&#xff08;RF&#xff09; 一、引言1. 简要介绍集成学习的概念及其在机器学习领域的重要性。2. 引出随机森林作为Bagging算法的一个典型应用。 二、随机森林原理1. Bagging算法的基本思想2. 随机森林的构造3. 随机森林的工作机制 三…

Samsung三星NP930XCJ-K01CN笔记本原厂Win10系统安装包下载

三星SAMSUNG笔记本电脑原装出厂Windows10预装OEM系统&#xff0c;恢复开箱状态自带系统 链接&#xff1a;https://pan.baidu.com/s/1Y3576Tsp8MtDxIpJGDucbA?pwdt0ox 提取码&#xff1a;t0ox 三星原装W10系统自带声卡,网卡,显卡,指纹,蓝牙等所有驱动、三星出厂主题专用壁纸…

vivado 在硬件中调试串行 I/O 设计-属性窗口

只要在“硬件 (Hardware) ”窗口中选中 GT 或 COMMON 块、在“链接 (Link) ”窗口中选中链接 &#xff0c; 或者在“扫描 (Scan)”窗口中选中扫描 &#xff0c; 那么就会在“ Properties ”窗口中显示该对象的属性。对于 GT 和 COMMON &#xff0c; 包括这些对象的所有属性、…

未雨绸缪:25岁Python程序员如何规划职业生涯,避免35岁职业危机?

一、程序员如何避免中年危机&#xff1f; 为了避免在35岁时被淘汰&#xff0c;程序员在25岁时可以采取一系列策略来规划自己的职业发展和提升技能。以下是我给大家整理的一些建议&#xff1a; 1. 持续学习 科技行业更新换代迅速&#xff0c;程序员需要保持对新技术和工具的敏…

揭秘大模型应用如何成为当红顶流?

Kimi广告神话背后的关键词战略 如果你生活在中国&#xff0c;你可能不认识ChatGPT&#xff0c;但你一定知道Kimi。无论是学生党还是打工人&#xff0c;都无法避开Kimi的广告。 刘同学在B站上搜教学视频时&#xff0c;弹出了一则软广&#xff0c;上面写着&#xff1a;“作业有…

SQL 基础 | BETWEEN 的常见用法

在SQL中&#xff0c;BETWEEN是一个操作符&#xff0c;用于选取介于两个值之间的数据。 它包含这两个边界值。BETWEEN操作符常用于WHERE子句中&#xff0c;以便选取某个范围内的值。 以下是BETWEEN的一些常见用法&#xff1a; 选取介于两个值之间的值&#xff1a; 使用 BETWEEN来…

批处理优化

1.4、总结 Key的最佳实践 固定格式&#xff1a;[业务名]:[数据名]:[id]足够简短&#xff1a;不超过44字节不包含特殊字符 Value的最佳实践&#xff1a; 合理的拆分数据&#xff0c;拒绝BigKey选择合适数据结构Hash结构的entry数量不要超过1000设置合理的超时时间 2、批处理优…

​【收录 Hello 算法】第 3 章 数据结构

第 3 章 数据结构 Abstract 数据结构如同一副稳固而多样的框架。 它为数据的有序组织提供了蓝图&#xff0c;算法得以在此基础上生动起来。 本章内容 3.1 数据结构分类3.2 基本数据类型3.3 数字编码 *3.4 字符编码 *3.5 小结

课时115:sed命令_进阶实践_高阶用法2

2.2.4 高阶用法2 学习目标 这一节&#xff0c;我们从 暂存实践、其他实践、小结 三个方面来学习。 暂存实践 简介 我们可以在缓存空间和暂存空间中进行数据的简单读取&#xff0c;还可以对数据进行一些复杂性的编辑操作常见的高阶命令P 打印模式空间开端至\n内容&#xff0…

Unable to find assembler. Install ‘yasm‘ or ‘nasm.‘ To build without

Unable to find assembler. Install yasm or nasm. To build without 一、概述二、解决办法 一、概述 系统&#xff1a;Ubuntu 22.04 在编译一个项目的时候提示我汇编器有一个问题&#xff0c;一个ysam 或者 nasm未安装 二、解决办法 sudo apt install yasm

银行智能化数据安全分类分级实践分享

文章目录 前言一、数据安全智能分类分级平台建设背景二、数据安全分类分级建设思路和实践1、做标签– 数据安全标签体系2、打标签– 鹰眼智能打标平台 3.03、用标签– 全行统一“数据安全打标签结果”服务提供前言 随着国家对数据安全的高度重视,以及相关法律法规的出台,数据…

【Leetcode每日一题】 分治 - 排序数组(难度⭐⭐)(69)

1. 题目解析 题目链接&#xff1a;912. 排序数组 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 归并排序&#xff08;Merge Sort&#xff09;是一种采用“分而治之”&#xff08;Divide and Conquer&#xff09;策略…