目录
1.换行、回车概念
/n:换行+回车(\r:回车)
2.缓冲区
如下图在vim编辑器中的命令模式下输入命令,在3号手册中查看sleep。
sleep是由Linux提供的接口,用于程序在执行时停下来休眠数秒。
如下图在命令行窗口中输入命令,在3号手册中查看usleep。usleep是由Linux提供的接口,用于程序在执行时停下来休眠数微秒。
sleep与usleep的区别是sleep休眠时间单位是秒,usleep休眠时间单位是微秒。
1秒=1000毫秒=1000 000微秒=1000纳秒
2.1缓冲区
情况一、加上\n
运行结果:先打印字符串换行休眠三秒再打印命令行提示符
情况二、不加\n运行结果:休眠三秒然后打印出字符串和命令行提示符
出现以上两种不同的情况是因为printf()函数不是直接向显示器文件写入,而是先向缓冲区中写入。
- 由键盘输入字符也是会立即显示到屏幕上的。
- 之前printf函数是向磁盘中写入,然后再向显示器中写入,现如今为了提高效率,向内存中写入而不是向磁盘中写入(由内存向内存拷贝数据要比由内存向磁盘拷贝数据要快);
- 由缓冲区向显示器中刷新,单次刷新量越大刷新次数越少,效率越高,但一次刷新太多用户看不过来,对于我们人来说习惯于按行读。综合来说按行刷新是最合理的。
2.2强制刷新
C语言中fflush函数用来强制将数据刷新到显示器上。
每一个C语言程序在执行开始之前会默认打开如下3个流:
- FILE* stdin:是标准输入流,对应的设备是显示器;
- FILE* stdout:是标准输出流,对应的设备是键盘;
- FILE* stderr:是标准错误流,对应的设备是显示器。
为什么C语言在开始执行程序之前会打开这3个标准流呢?
因为程序对大多数用户来说是用来做计算的,用户由键盘输入,经过程序计算,再由显示器给用户显示出来,显示器和键盘被用户经常使用,那C语言设计者就想既然显示器和键盘被多次用,那在程序开始执行之前默认将其打开。
3.进度条程序
Makefile文件
cpp
ProgressBar.exe:Main.c ProgressBar.c
gcc $^ -o $@ -std=c99
PHONY:clean
clean:
rm -f ProgressBar.exe
ProgressBar.h
cpp
#pragma once
#include <stdio.h>
void ProBar1();
void ProBar2(double fileSize, double current);
ProgressBar.c
cpp
#include "ProgressBar.h"
#include <unistd.h>
#include <string.h>
//void test()
//{
// printf("hello\n");
//}
#define STYLE '='
#define LENGTH 101
//version 1
void ProBar1()
{
char bar[LENGTH];
memset(bar,'\0',LENGTH);
char state[]={'|','/','-','\\'};
int cnt=0;
while(cnt<=100)
{
printf("[%-100s][%3d%%][%c]\r",bar,cnt,state[cnt%4]);
fflush(stdout);
bar[cnt++] = STYLE;
usleep(50000);
}
printf("\n");
}
//version 2
void ProBar2(double fileSize, double current)
{
double rate = (current*100.0) / fileSize;
int loopCount = (int)rate;
char bar[loopCount+1];
memset(bar,STYLE,loopCount);
bar[loopCount] = '\0';
char state[]={'|','/','-','\\'};
printf("[%-100s][%.1lf%%][%c]\r",bar,rate,state[loopCount%4]);
fflush(stdout);
}
Main.c
cpp
#include "ProgressBar.h"
#include <unistd.h>
double bandwith = 1.2*1000000;
void download(double fileSize)
{
double current = 0.0;
printf("download begin\n");
while(current<=fileSize)
{
ProBar2(fileSize,current);
double old = current;
current += bandwith;
if(old<fileSize && current>fileSize)
{
current = fileSize;
}
sleep(1);
}
printf("\n");
printf("download end fileSize:%lf\n",fileSize);
}
int main()
{
// test();
// ProBar();
// ProBar2(100,56.6);
// printf("\n");
// ProBar2(67,66);
// printf("\n");
// ProBar2(100,1.2);
// printf("\n");
double file = 100.2*1024*1024;
download(file);
return 0;
}