Индикатор выполнения Linux

1. Понимание возврата каретки и перевода строки

  В знакомом нам языке C символ новой строки может перейти к началу следующей строки, но на самом деле эта операция состоит из двух шагов: \r (возврат каретки) и \n (новая строка).

\rEnter — вернуться к началу этой строки
\nNewline — начать новую строку

2. Понимание буферизации строк

  В памяти зарезервировано пространство для буферизации входных или выходных данных, и это зарезервированное пространство называется буфером. Давайте разберемся с концепцией буферизации строк на нескольких примерах кода.

1. Код 1 и 2 (понимают возврат каретки и перевод строки)

Код один:

  1#include <stdio.h>
  2 int main()
  3 {
    
    
  4     printf("hello world\n");                                                                                                                               
  5     return 0;
  6 }
Код два:
  1#include <stdio.h>
  2 int main()
  3 {
    
    
  4     printf("hello world\r");                                                                                                                               
  5     return 0;
  6 }

  Нетрудно обнаружить, что \n можно распечатать, а \r распечатать нельзя, потому что режим отображения таков, что буфер обновления строки буферизуется построчно, без \n его нельзя обновить сразу.\r После возврата к началу строки она будет перезаписана, приглашение оболочки перезапишет ранее написанное «hello world». Если мы не добавим \r к «hello world», перезапись не будет выполнена, и приглашение оболочки запишет «hello world» наоборот

следующее:

2. Код три и четыре (понимание функций сна и функции промывания)

  Буферизация строки — это своего рода стратегия очистки буфера. В режиме буферизации строки, когда во вводе и выводе встречается символ новой строки '\n', буфер будет обновлен. Ниже мы знаем три файла заголовков <unistd.h> функция

спать спатьs l ee p : функция сна в Linux, устройство находится в состоянии сна
usleepu s l ee p : То же, что и сон, единица измерения мс (т.е. 10-6м)
fflush fflushff l u s h : очистить буфер

Код 3:

  1 #include <stdio.h>
  2 #include <unistd.h>                                                                                                                                       
  3 int main()
  4 {
    
    
  5     printf("hello world");
  6     sleep(3);
  7     return 0;
  8 }

  Мы знаем, что операторы кода функции выполняются последовательно сверху вниз, но мы видим, что он засыпает на три секунды, а затем печатает «hello world»,Причина в том, что данные хранятся в буфере и не обновляются активно. Когда программа завершается, данные, хранящиеся в буфере, автоматически обновляются.Если мы хотим обновить заранее, мы можем вызвать fflush fflushff l u s h функция для очистки буфера

Код четыре:

  1 #include <stdio.h>
  2 #include <unistd.h>                                                                                                                                       
  3 int main()
  4 {
    
    
  5     printf("hello world");
  6		fflush(stdout);
  7		printf("\n");
  8     sleep(3);
  9     return 0;
  10}

  На этот раз «hello world» печатается напрямую, мы добавляем \n , чтобы избежать оболочки.Приглашение оболочки появляется после «hello world» .

3. Простой обратный отсчет

1. Отображение эффекта

  С помощью вышеуказанной подготовительной работы мы можем понять принцип работы обратного отсчета и индикатора выполнения.Далее мы сначала дадим код и эффект, а затем поговорим о деталях.

2. Код обратного отсчета

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 int main()
  4 {
    
    
  5     int cnt=10;
  6     while(cnt>=0)
  7     {
    
    
  8         printf("%-2d\r",cnt);
  9         fflush(stdout);
 10         sleep(1);
 11         cnt--;                                                                                                                                            
 12     }
 13     printf("\n");
 14     return 0;
 15 }

3. Проведите анализ процесса

1. Определите переменную обратного отсчета cnt , пусть она постепенно уменьшается
2. Ядро состоит в том, чтобы использовать \r , чтобы вернуться к началу строки буфера для перезаписи, а затем fflush постоянно обновляет ее
3. Настройка формата при печати cnt= =10 , напечатать в буфер На самом деле это символ 1 и символ 0. Если мы не используем 2d% для настройки формата, а используем d% , то перезапись будет охватывать только первый символ 1 11 позиция, а второй символ0 00 , он остается в исходной позиции буфера, поэтому обратный отсчет станет следующим:
  10->90->80->70->60->50->40->30->20->10->00,-2d%добавьте знак минус, чтобы убедиться, что он выровнен по левому краю
4, добавьте\nпосле обратного отсчета,оболочкине появится после обратного отсчета

4. Индикатор выполнения

1. Отображение эффекта


2. Штрих-код выполнения

   makefile

  1 processbar:processBar.c main.c                                                                                                                            
  2     gcc -o $@ $^
  3 .PHONY:clean
  4 clean:
  5     rm -f processbar

   Заголовочный файл processBar.h

  1 #pragma once                                                                                                                                              
  2 #include<stdio.h>
  3 
  4 #define SIZE 102
  5 #define BODY '='
  6 #define TAIL '>'
  7 
  8 extern void processbar(int rate);
  9 extern void initbar();

  .c файл processBar.c

    1 #include "processBar.h"
    2 #include <string.h>
    3 #include <unistd.h>
    4 
    5 #define LIGHT_GREEN  "\033[1;32m" //亮绿色
    6 #define NONE "\033[m" 			//截断
    7 
    8 const char *lable="|/-\\";
    9 char bar[SIZE];
   10 
   11 void processbar(int rate)
   12 {
    
    
   13     if(rate<0 || rate > 100)
   14         return;
   15	  //没有\n,就没有立即刷新,因为显示器模式是行刷新
   16     printf(LIGHT_GREEN"[%-100s]"NONE"[%d%%][%c]\r",bar,rate,lable[rate%4]); 
   17     fflush(stdout);
   18     bar[rate++]=BODY;
   19     if(rate<100)
   20          bar[rate]=TAIL;
   21 }                                                                                                                                                       
   22                         
   23 void initbar()
   24 {
    
                 
   25     memset(bar,'\0',sizeof(bar));
   26 } 

  .c файл main.c

  1 #include "processBar.h"
  2 #include <unistd.h>
  3 
  4 typedef void(*callback_t)(int);
  5 void downLoad(callback_t cb)
  6 {
    
    
  7     initbar();
  8     int total=1000; // 1000MB
  9     int curr=0;     //0MB
 10     while(curr<=total)
 11     {
    
    
 12         // 进行某种下载任务
 13         usleep(50000);  //模拟下载花费时间
 14         int rate=curr*100/total;//更新进度
 15 
 16         cb(rate);       //回调展示进度
 17         //processbar(curr*100/total); 
 18 
 19         curr+=10;       // 循环下载了一部分,更新进度
 20     }
 21     printf("\n");
 22 }
 23 
 24 
 25 int main()
 26 {
    
    
 27     printf("download 1:\n");
 28     downLoad(processbar);
 29     printf("download 2:\n");                                                                                                                              
 30     downLoad(processbar);  
 31     printf("download 3:\n");  
 32     downLoad(processbar);  
 33     printf("download 4:\n");  
 34     downLoad(processbar); 
 35		return 0;
 36 }

3. Проведите анализ процесса

  стиль индикатора выполнения

Стиль индикатора выполнения:
   основной стиль заключен в две квадратные скобки, а средняя => продвигается вперед. Например: [======>] Положение
  квадратных скобок с правой стороны основного тела остается неизменным. , а средний элемент продолжает продвигаться вперед, например: [ => ]
  Таким образом, мы определяем среднее тело = макрос как BODY , а заднюю сторону > макрос как TAIL

Процент индикатора выполнения:
  отображать текущий прогресс загрузки, отображаемый в [rate%], скорость изменяется в зависимости от хода индикатора выполнения, а для печати % (экранирующий символ) требуется два %%

Символ вращения индикатора выполнения:
  отображение стиля загрузки, вы можете использовать вращающийся символ, например стиль [], непрерывно вращать по часовой стрелке, а затем "| / - \" , обратите внимание, что \ также является escape-символом, поэтому требуются два символа \\ , Для этого мы определяем указатель метки , указывающий на константную строку const char * lable=" | / - \"

Цвет индикатора выполнения: ссылка на цвет языка C
  Мы можем раскрасить индикатор выполнения в соответствии с нашими собственными предпочтениями, здесь мы находим справочную таблицу цветов
  и определяем светло-зеленый макрос как #define LIGHT_GREEN Макрос в конце "\033[1;32m "
  определяется как #define NONE "\033[m"

  Метод реализации индикатора выполнения

  Зарезервируйте размер индикатора выполнения как 100 = плюс 1 > плюс сохраните положение \0 и создайте массив столбцов со 102 единицами (определено как SIZE в макросе). Функция processbar() выводит индикатор прогресса с определенной скоростью, после \r возвращается в начало строки, fflush обновляет буфер, и при этом вставляет = в конец массива баров , а затем вставляет > , обратите внимание, что когда скорость равна 100, индикатор выполнения загружается, поэтому нет необходимости вставлять >
  для имитации выполнения задачи загрузки и передавать функцию processbar() метода реализации в качестве параметра для имитации downLoad() функция загрузки , для этого мы определяем указатель на функцию типа processbar() и переименовываем его в callback_t . Мы определяем размер пакета загрузки как общую суммуитого , текущий прогресс - текущий текущийc u rr , поэтому скорость выполнения равнаrate=curr*100/total. Используйтеusleep, чтобы имитировать время загрузки, а затем верните обратно, чтобывызвать функцию processbar()для реализации индикатора выполнения Наконец, учитывая вторую загрузку,массив баров заполненочищатьмассив баровкаждый раз мы вызываемфункцию downLoad()

Supongo que te gusta

Origin blog.csdn.net/Front123456/article/details/131653270
Recomendado
Clasificación