Linux小程序 - /r/n与缓冲区的简单概念

今天我们来简单地讲述一下C中的/r/n字符与缓冲区的概念

/r/n

/r:回车

/n:换行

下面从一段简单地C程序来介绍:

 

#include <stdio.h>
  
int main()
{
    printf("Hello world\n");                                               
    return 0;
}


#include <stdio.h>
  
int main()
{
    printf("Hello world\r");                                               
    return 0;
}

当带有/n的代码执行结束之后就得到 :

当执行带有/r的代码,得到的结果如下:

 当我们什么都不带的时候,我们就会得到如下的代码:

为什么会没有打印出来数据呢,就是因为我们使用了 /r 这个字符,它将光标直接回到了最开始。

为了更好地理解这个问题我们来讲述一下第二个话题缓冲区

缓冲区

我们对代码进行如下的修改,让其在printf函数之后停滞3秒,然后在继续执行:

#include <stdio.h>
#include <unistd.h>
int main()
{
    printf("Hello world\n");
    sleep(3);                                               
    return 0;
}


#include <stdio.h>
  
int main()
{
    printf("Hello world\r");                                               
    sleep(3);
    return 0;
}

首先是带有\n的代码执行结果: 

然后是带有\r的代码执行结果:

最后是没有这两种字符的代码执行结果: 

从表面上看好像是先执行的sleep,然后在执行的printf,但是我们知道C是以从上至下的顺序结构运行的,一定是先运行的printf。其中根本原因就是在sleep的3秒期间hello的这个字符串没有被刷新,被存放在了缓冲区。当我们添加了\n之后,缓冲区就会被刷新,显示器上就会显示出换行符之前的所有缓冲区存放的数据。

在printf后添加语句 fflush(stdout); 就可以刷新缓冲区。

当我们对缓冲区进行刷新之后就能够得到printf输出的结果:

还可以发现刷新完缓冲区之后,光标的位置是在最开始的。 

利用/r完成的倒计时例子

int main()                                                                
{                                                                         
  int i = 9;                                                              
  for (; i >= 0; i--)                                                     
  {                                                                       
    printf("%d\r", i);                                                    
    fflush(stdout);                                                          
    sleep(1);      
  }      
  return 0;      
}   

利用\r的回车和刷新缓存区的功能,就可以仿照倒计时的功能。还需要注意的一点是:回车并不会删除缓冲区中的内容。例如我们的倒计时从10开始:

可以通过将printf中的%d写成%2d的形式来解决这种问题,在C中的格式是右对齐的。 

进度条的例子

#define SIZE 101    
#define STYLE '='    
#define ARR '>'    
void process()    
{    
    const char* label = "/|\\-";                                                                                          
    char bar[SIZE];    
    memset(bar, '\0', sizeof(bar));    
    int i = 0;    
    while (i <= 100)    
    {    
        printf("[%-100s][%d%%][%c]\r", bar, i, label[i%4]);    
        fflush(stdout);    
        bar[i++] = STYLE;    
        if (i != 100) bar[i] = ARR;    
        usleep(100000);    
    }    
    printf("\n");    
} 

利用前文所述的内容就可以在Linux的环境下编写成一个进度条的例子。

printf彩色输出

此外,讲解一个使用printf输出其他颜色的语句的方法:

控制命令

控制命令以\033[开头,以m结尾,而中间则是属性码,属性代码之间使用;分隔,如\033[1;34;42m

属性代码

下面给出部分属性代码:

通用格式控制:

属性代码功能
0重置所有属性
1高亮/加粗
2暗淡
4下划线
5闪烁
7反转
8隐藏

前景色:

属性代码颜色
30黑色
31红色
32绿色
33黄色
34蓝色
35品红
36青色

背景色:

属性代码颜色
40黑色
41红色
42绿色
43黄色
44蓝色
45品红
46青色

printf彩色输出转载自:C/C++——printf彩色输出 - LewKI - 博客园 (cnblogs.com)

进过颜色的修改我们可以得到新的进度条样式:

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值