Question :
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.
Answer :
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 worldn");
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("nGoodbyen");
}
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 texton");
cls();
printf("Esta é uma nova linha de texton");
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("nnnn 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 .
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 ("nnCarregando: nn");
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 ("nn Fimnn");
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.
}