[Linux] Te enseño paso a paso cómo hacer un subprograma de barra de progreso

[Linux] Crear un subprograma de barra de progreso

\n y \r caracteres en lenguaje C

Hay dos tipos de caracteres en lenguaje C:

  • Caracteres visualizables
  • personajes de control

Los caracteres visualizables son caracteres como el carácter a, y los caracteres de control son caracteres de control como \n.

Para que podamos hacer la barra de progreso, sólo debemos prestar atención a dos personajes de control:

  • \r – realizar la operación de retorno de carro
  • \n: realizar operaciones de avance de línea y retorno de carro

Explicación: \n en sí mismo es un carácter de nueva línea, pero el lenguaje C lo analiza en una nueva línea más un retorno de carro.

Para comprender mejor el papel de los caracteres \r y \n, necesitamos hacer algunas pruebas. Para facilitar la compilación, cree un archivo MAKE. El contenido del archivo es el siguiente:

mytest:test.c
	gcc -o mytest test.c
.PHONY:clean
clean:
	rm -f mytest

Primero ejecute el siguiente código:

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

ilustrar:

  • fflush(stdout) actualiza el búfer de salida estándar para facilitar la observación del fenómeno.
  • dormir es la función de suspensión del sistema Linux.

Los resultados de la ejecución son los siguientes:

imagen-20230730125207629

hello worldDespués de imprimir , el programa duerme y el "cursor" está en la siguiente posición en la misma línea.

imagen-20230730125310098

Una vez finalizada la hibernación, la impresión comenzará desde la posición del cursor, por lo que la [qxm@aliyun-centos review]$línea de comando se imprimirá inmediatamente después hello world.

Luego ejecute el siguiente código:

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

Los resultados de la ejecución son los siguientes:

imagen-20230730125541374

Dado que el lenguaje C analiza \n en un avance de línea seguido de un retorno de carro, el programa se suspenderá hello worlddespués y el "cursor" irá al principio de la siguiente línea.

imagen-20230730123307921

Una vez finalizada la hibernación, la impresión comenzará desde la posición del cursor, por lo que [qxm@aliyun-centos review]$la línea de comando se imprime al comienzo de la siguiente línea.

Finalmente ejecute el siguiente código:

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

ilustrar:

  • fflush(stdout) actualiza el búfer de salida estándar para facilitar la observación del fenómeno.
  • dormir es la función de suspensión del sistema Linux.

Los resultados de la ejecución son los siguientes:

imagen-20230730130940986

Dado que \r es un retorno de carro, el programa se suspenderá hello worlddespués y el "cursor" volverá al principio de la línea.

imagen-20230730123307921

Una vez finalizada la hibernación, la impresión comenzará desde la posición del cursor, por lo que la línea de comando sobrescribirá [qxm@aliyun-centos review]$la original .hello world

imagen-20230730131108150

Estrategia de actualización del búfer

En el sistema Linux, el lenguaje C primero almacenará los caracteres que se imprimirán en el búfer. Solo cuando los caracteres en el búfer se actualicen en la pantalla se podrán ver en la pantalla. La situación de actualización del búfer es la siguiente:

  • Al encontrar \n, todos los caracteres antes de \n aparecerán en la pantalla.
  • El búfer se vacía automáticamente cuando finaliza el programa.

Para la prueba del buffer, ejecutamos el siguiente código:

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

Los resultados de la ejecución son los siguientes:

imagen-20230730132019107

Debido a que el búfer no se vacía, no se imprime nada mientras el programa está inactivo.

imagen-20230730133131040

Después de ejecutar el programa, el búfer se actualiza e hello worldimprime automáticamente.Sin embargo, dado que el retorno de carro \r devuelve el "cursor" al principio de la línea, la impresión del símbolo del sistema sobrescribe la impresión anterior.

Luego ejecute el siguiente código:

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

Los resultados de la ejecución son los siguientes:

imagen-20230730132354920

Debido a un encuentro\nLos datos en el búfer se actualizaron antes de dormir.

imagen-20230730132526954

Después de que el programa hiberna, la línea de comando comienza a imprimir desde la posición del cursor.

Escribir código de barras de progreso

Cree los siguientes archivos para formar la estructura del código:

  • myproc.h: la declaración que contiene el código de barras de progreso
  • myproc.c: implementación del código de barras de progreso de guardado
  • main.c – llamar al código de barras de progreso

La estructura principal del archivo myproc.h es la siguiente:

#pragma once 
#include <stdio.h>
extern void process();

La estructura principal del archivo myproc.c es la siguiente:

#include "myproc.h"
void process()
{
    
    
  //...
}

La estructura principal del archivo main.c es la siguiente:

#include "myproc.h" 
int main()
{
    
    
  process();
  return 0;
}

Al mismo tiempo, cree un archivo MAKE y escriba el siguiente contenido dentro del archivo MAKE:

myproc:myproc.c main.c
	gcc -o myproc myproc.c main.c
.PHONY:clean
clean:
	rm -f myproc

Después de establecer la estructura del código, escriba el siguiente código para que actúe como una barra de progreso gráfica:

#include "myproc.h"
#include <string.h>
#include <unistd.h>

#define STYLE '='
#define ARROW '>'
#define SIZE 101

void process()
{
    
    
  char buf[SIZE];
  memset(buf, 0 , SIZE);
  int i = 0;
  while(i <= 100)
  {
    
    
    printf("[%-100s]\r", buf);
    fflush(stdout);
    buf[i++] = STYLE;
    if(i != 100 )buf[i] = ARROW;
    usleep(100000);
  }
  printf("\n");
}

Primero cree una cadena para guardar el buf de la barra de progreso gráfica que se imprimirá, inicialícelo y luego imprima el buf alineado a la izquierda e imprímalo con una longitud de 100 caracteres.

Cada vez que se completa la impresión, el retorno de carro sobrescribe la impresión anterior y el búfer se actualiza para que la impresión se muestre en la pantalla y se utiliza una función de suspensión para cargar el progreso.

El efecto de impresión es el siguiente:

111

Además de la barra de progreso gráfica, también se debe configurar una visualización de progreso digital, por lo que es necesario modificar la impresión, de la siguiente manera:

printf("[%-100s][%d%%]\r", buf, i);

Aumente el porcentaje de progreso de la impresión a medida que se muestra el progreso de la digitalización, %% se escapará a % y se imprimirá en la pantalla.

El efecto de impresión es el siguiente:

222

Finalmente, se agrega un cursor giratorio para indicar que la barra de progreso se está ejecutando continuamente, por lo que es necesario modificar la impresión, el código final es el siguiente:

#include "myproc.h"
#include <string.h>
#include <unistd.h>

#define STYLE '='
#define ARROW '>'
#define SIZE 101

void process()
{
    
    
  const char* cursor = "|/-\\";
  char buf[SIZE];
  memset(buf, 0 , SIZE);
  int i = 0;
  while(i <= 100)
  {
    
    
    printf("[%-100s][%d%%][%c]\r", buf, i, cursor[i%4]);
    fflush(stdout);
    buf[i++] = STYLE;
    if(i != 100 )buf[i] = ARROW;
    usleep(100000);
  }
  printf("\n");
}

Se agrega una cadena de cursor para guardar el estilo del cursor giratorio, donde \\ se escapará a \, debido a que se imprimen 4 caracteres en un bucle en el cursor giratorio, por lo que la cadena de estilo se genera en módulo 4.

El resultado final de la demostración de la barra de progreso es el siguiente:

333

Supongo que te gusta

Origin blog.csdn.net/csdn_myhome/article/details/132080072
Recomendado
Clasificación