一:\r 和 \n
\r --- 回车 --- 使光标回到这一行的开头
\n --- 换行 --- 会来到下一行与之平行的位置
缓冲区的问题:
<1>: \n 的示例
正常输出 hehehehe 。
<2>: \r 的示例
为了方便观察,加入一个 sleep (休眠函数),使其休眠2秒,观察其结果:
现象为:停顿两秒后,没有输出 hehehehe ,而是出现输入命令行。
<3>: 两者对比
上述两种情况出现是行缓冲区存在导致的,\n 是一种刷新策略(行刷新),有刷新缓冲区的作用,所以它可以立即显示输出结果。而在 \r 的程序时,使用 printf 函数,每次打印一个字符,光标就会向后移动,当走到 \r 时,光标又会回到该行的起始位置,最终会被命令行提示符覆盖,导致程序得不到想要的结果。
<4>: 刷新输出缓冲区(ffush(stdout))
在休眠两秒之前,刷新输出缓冲区:
现象:hehehehe 程序运行后,立刻输出,光标始终位于一行的起始位置,两秒后,被命令行提示符覆盖掉。
<5>: 不带 \r 和 \n 的情况
运行现象为:先休眠两秒,然后输出hehehehe , 同一行后面输出命令行提示符。
我们知道,在C语言中代码的执行顺序是由上而下进行的,所以肯定是先执行的 printf 函数,然后执行 sleep 函数,但是代码的运行现象并非先打印后休眠,而是先休眠后打印 --- 为什么???
原因:hehehehe 没有被刷新,在 sleep 期间 hehehehe 一直保留在缓冲区中,直到程序结束,系统自动刷新缓冲区才会显示出来,所以我们观察到的现象为先休眠两秒,然后输出 hehehehe 。
二:进度条代码实现
1.倒计时示例
经过上述缓冲区问题,我们可以知道,\r 前面的内容如果要打印出来,需要及时刷新输出缓冲区(通过 fflush 函数实现),我们为了看到倒计时的结果,可以让其每隔一秒钟打印一次。
QQ录屏20231015215917
我们发现所得现象并不是我们理想的现象,若要得到理想状态的现象,需要修改 printf 的输出格式
在此处,需要注意打印的格式,%2d 表示预留两个位置, %d 表示预留一个位置。
QQ录屏20231015220103
2.进度条(简易版)
我们实现一个前面显示图形,然后显示加载进度,最后显示其是否在运行(或者卡住)的形式。
我们可以看到该代码,最后的结果会被命令行提示符覆盖掉,在此处,我们在最后使用 \n 刷新缓冲区。
接下来,我们来解决,打印方向的问题,常规来说应该从右向左,在此处为从左向右,我们需要改变 printf 的输出格式。即在输出格式前面加 - 号。
接下来,我们来打印一个标识,来辅助说明,程序是否在运行:
至此,一个简单的进度条就完成了。
我们观察一下动态版的进度条:
QQ录屏20231015233138
2.进阶版
结合具体的场景,实现进度条;示例为我们需要下载一个东西,其已经下载的大小和东西大小的比率来控制进度条的进度:
我们观察一下动态的进度条:
QQ录屏20231016211813
3.美化版
我们的输出,一般都是黑底白字,其实 printf 函数可以实现彩色打印,在此处我们参考文章:printf函数彩色打印
在此处 我们对上述代码(printf函数部分)进行修改,使其可以进行彩色输出。
(示例代码为黄底白字):
我们观察一下动态的进度条:
QQ录屏20231016213031