How to effect loading from the terminal in only one line?

4

How can I do a loading effect by giving refresh on only one line of the terminal when running a program in c?

Example:

  

loading ...

The points are increasing.

I can do this in a while loop but only by clearing the screen with the

system("clear");

I would just like to update a line.

    
asked by anonymous 14.04.2015 / 23:28

3 answers

5

You can print a CR ( \r , carriage return, which returns the cursor to the beginning of the line), clean the line and then con- tune printing your points, as in the example below:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>

void main() {
    printf("Hello world\n");
    for (int i = 0; i < 10; i++) {
        printf("Carregando %d", i);
        for (int j = 0; j < 40; j++) {
            printf(".");
            Sleep(20);
        }
        printf("\r");
        for (int j = 0; j < 60; j++) {
            printf(" "); // apaga a linha anterior
        }
        printf("\r");
    }
    printf("\nGoodbye\n");
}
    
14.04.2015 / 23:59
3

If you are using Linux (as seems to be the case given your attempt to call clear ), an * interesting solution is to use the X-Term commands to clear the screen and move the cursor to line 0 and column 0. For example:

#include <stdio.h>

void cls(void)
{
    printf("3[2J");   // Limpa a tela
    printf("3[0;0H"); // Devolve o cursor para a linha 0, coluna 0
}

int main(void)
{
    printf("Esta é uma linha de texto\n");
    cls();
    printf("Esta é uma nova linha de texto\n");
    return 0;
}

If your idea is just to "animate" a loading message, instead of cleaning the screen it is more practical and quick to simply move the cursor back to the initial column. Here is an example that animates the dots:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>

int dots = 1;
void reset();
unsigned int alarm();
void animation(int signo);


int main(void)
{
    printf("\n\n\n\n      Carregando");
    signal(SIGALRM, animation);
    alarm(1);

    while(1)
        getchar();

    return 0;
}

void reset(void)
{
    printf("3[10D");         /* Move 10 colunas para a esquerda */
    printf("          ");       /* Imprime 10 espaços em branco */
    printf("3[10D");         /* Move 10 colunas para a esquerda */
}

unsigned int alarm (unsigned int seconds)
{
    struct itimerval old, new;
    new.it_interval.tv_usec = 0;
    new.it_interval.tv_sec = 0;
    new.it_value.tv_usec = 0;
    new.it_value.tv_sec = (long int) seconds;
    if (setitimer (ITIMER_REAL, &new, &old) < 0)
        return 0;
    else
        return old.it_value.tv_sec;
}

void animation(int signo)
{
    signal(SIGALRM, animation);
    alarm(1);

    (void)(signo); /* apenas ignora o parâmetro */

    printf(".");
    dots++;
    if(dots > 10)
    {
        dots = 1;
        reset();
    }
}
  

Note that this solution does not work in Windows. If you want to use something   more standardized to emulate its own terminal, it is worth evaluating the    ncurses (which also has a port for Windows ).

* My answer was created with help from this SOEN answer .

    
15.04.2015 / 02:32
0

Thanks for the answers but it did not work for me, I use linux, I tried to adapt them, but the result did not work out as I intended.

I was able to solve it, I adapted it from the code and the code for @carlosfigueira , by analyzing the code of the link you can see that there is a problem in it as i increases.

Then I had to understand the operation of a parameter of printf , \r and only then could I formulate a solution.

The solution is this:

  #include <stdio.h>
  #include <time.h>

  void limpa_linha(void);

  int main (int argc, char **argv){    
     int i, j;

     system ("clear");//limpa tela
     printf ("\n\nCarregando: \n\n");          

     for (i = 0; i <= 100; i++){             
        printf ("%d%%  ", i);      
        fflush (stdout);//garante a escrita de dados imediatamente na tela                  
        //repare mod 10, eu limito a qtd de pontos q serao gerados
        for (j = 0; j < i%10; j++){
           printf(".");
        }  
        fflush (stdout);//garante a escrita de dados imediatamente na tela
        usleep(500000);//função espera por tempo, parametro em microsegundos.
        limpa_linha();                    
     }                 
     printf ("\n\n Fim\n\n");            
     return 0;
  }

  void limpa_linha(){
     int i;//indice do caracter na linha
     int max_caracter=50;//indica o maximo de caracter que a linha pode chegar a ter, para linhas com mt texto, coloque um nmr bem maior
     printf("\r");//retorna para o inicio da linha que pretende reutilizar, isso não limpa a linha, apenas posiciona cursor ao inicio da linha

     //Agora precisamos limpar a linha,
     //substitui todos os caracteres existentes por espaço em branco
     for(i=0;i<max_caracter;i++){
        printf(" ");//vai preenchendo a linha com espaços em branco
     }

     printf("\r");//volta ao inicio da linha , dessa vez ela está em branco.

  }
    
15.04.2015 / 18:51