[Linux] The difference between carriage return and line feed + simple implementation of countdown and progress bar (apply what you have learned)

Preface: This article mainly explains the difference between carriage return and line feed. After understanding the difference between carriage return and line feed, we will guide you to implement a simple countdown program. We will use the carriage return and line feed learned in this article to apply what we have learned.


1. Understand carriage return and line feed

In the C language, many characters are involved, one is a displayable character, and the other is a control character. Displayable characters are like 'a', 'b', etc., and control characters are characters like '\n'.

\n(换行): Make the cursor jump from the current line to the next line, but it should be noted that the cursor just jumps down vertically, it is not like we usually press the Enter key, the cursor will directly change the line and go to the beginning of the next line.
\r(回车): Return the cursor to the original position.
Old-fashioned keyboard map:insert image description here

Test the carriage return and line feed, and observe the phenomenon:

(1) Both \r and \n exist

Phenomenon : It is equivalent to a line break, jump directly to the beginning
code of the next line :

#include<stdio.h>
#include<unistd.h>
int main()
{
    
    
	printf("hello world!\r\n");
	sleep(2);
	return 0;
}

Running result :
insert image description here

(2) \r and \n do not exist

Phenomenon : wait for 2 seconds before printing hello world!
But it is not to execute sleep first and then execute printf, it must be executed from top to bottom.
During sleep, hello world! It's just not refreshed, it is saved in the buffer, and the buffer is refreshed and printed after the program ends.
code :

#include<stdio.h>
#include<unistd.h>
int main()
{
    
    
	printf("hello world!");
	sleep(2);
	return 0;
}

Running result :
insert image description here

(3) Only\n

Phenomenon : Equivalent to line feed + carriage return
Explanation : No matter whether you add \n or not, the data will be saved in the buffer first, and the buffer strategy of the buffer is involved here: line buffering. Line buffering - as long as a newline character is encountered, the contents of all previous buffers including the newline character will be flushed out. (There are many refresh strategies, this is just one of them) So when encountering \n, first refresh the buffer and print data in sequence, then wait for two seconds, the program ends, and then print the command line.

(4) Only \r

Phenomenon : Sleep for 2 seconds, and then you can't see the printed information, only the linux command line is output.
Explanation : \r will return to the beginning, after the data storage enters the buffer, wait for two seconds, the program is about to end, first print hello world! , when \r is encountered after the printing is completed, the cursor returns to the beginning of the line, and then the command line needs to be printed, at this time, the command line will display hello world! It is overwritten, ( the program ends –> the data in the buffer is refreshed –> the buffer refresh string is printed out ) and because the two printing speeds are too fast, it seems that the result is the same as no printf output.
Note: If you don't see "hello world", it doesn't mean it is discarded, it's just temporarily stored in the buffer.
code :

#include<stdio.h>
#include<unistd.h>
int main()
{
    
    
	printf("hello world!\r");
	sleep(2);
	return 0;
}

Running result :
insert image description here
Supplement :
Here, after printf, use fflush(stdout); to refresh the buffer first hello world! Print it out, then sleep and wait for 2 seconds to end the program, you can clearly see the process.

2. Simple implementation of countdown program

#include<stdio.h>
#include<unistd.h>
int main()
{
    
    
	int i = 10;
	while(i, i >= 0, i--)
	{
    
    
        printf("%2d\r",i);//输出两位数,10以后要在第二位刷新数据,所以用%2d
		fflush(stdout);//刷新缓冲区
		sleep(1);
	}
	printf("\n");
	return 0;
}

3. Realize the progress bar program

Create 4 files in the current directory, as follows:
insert image description here

//proc.h头文件
#pragma once

#include<stdio.h>

extern void process();   

//proc.c进度条的具体实现函数
#include"proc.h"
#include<unistd.h>
#include<string.h>

#define STYLE '='//进度条字符,可定义你们想要的样式
#define SIZE 102 //给'\0',>箭头留两个位置
#define ARR '>'//进度条前面的箭头,加载完毕箭头消失
 
void process()
{
    
    
     const char* lable="|/-\\";//选择光标
     char bar[SIZE];//存放进度字符的数组
     memset(bar,'\0',sizeof(bar));//初始化进度条数组
 
     int i=0;
     while(i<=100)
     {
    
    
     	 //打印进度条,添加背景颜色为荧光绿,还有%进度,以及旋转光标
         printf("[\033[42;32;31m%-100s\033[0m][%d%%][%c]\r",bar,i,lable[i%4]);                                                                                                    
         fflush(stdout);//由于printf是以\r结尾,所以我们需要将缓冲区的结果刷新到显示屏上
         bar[i++]=STYLE;
         //加载完毕,箭头消失
         if(i!=100)
             bar[i]=ARR;
 
         usleep(100000);
     }
     printf("\n");
 }
 
 //main.c主函数,去调用进度条函数
 #include"proc.h"
                                                                                                                                                                                  
 int main()
 {
    
    
     process();
     return 0;
 }

//Makefile项目自动化构建工具
Processbar:main.c proc.c
     gcc main.c proc.c -o Processbar 
 .PHONY:
 clean:
     rm -f Processbar  

Progress bar running result :
insert image description here

Guess you like

Origin blog.csdn.net/weixin_63449996/article/details/130080074