1

I'm having trouble adding progress bar for my calculation tool (written in c). Having a simple progress bar code, I can print progress:

void print_progress(float progress) 
{
    int barWidth = 70;
    int pos = barWidth * progress;

    printf("%c",'[');

    for (int i = 0; i < barWidth; ++i) 
    {
        if (i < pos) {
            printf("%c",'=');
        }
        else if (i == pos) {
            printf("%c",'>');
        }
        else {
            printf("%c",' ');
        }
    }

    printf("] %f%% \r",(progress * 100.0));
    fflush(stdout);
}

Though, it prints only a fixed width progress bar. How can I change this to read the screen width and print a full-width progress bar? (Like wget or apt-get progress bars)

UPDATE

What I tried so far is to read terminal width using ioctl :

struct winsize max;
ioctl(0, TIOCGWINSZ , &max);
printf ("columns %d\n", max.ws_col); // Always 70

And also I don't want to add a dependency like ncurses...

UPDATE 2

Final (not working) version:

void loadbar(unsigned int x, unsigned int n, unsigned int max_width) {
    struct winsize ws;
    ioctl(0, TIOCGWINSZ, &ws);
    int barWidth = ws.ws_col;
    if(barWidth > max_width) {
        barWidth = max_width;
    }
    float ratio  =  x/(float)n;
    int   c      =  ratio * barWidth;
    printf("%s","[");
    for (x=0; x<c; x++) {
        printf("%s","=");
    }
    printf("%s",">");
    for (x=c+1; x<barWidth; x++) {
        printf("%s"," ");
    }
    printf("] %03.2f%%\r",100.0*ratio);
    fflush(stdout);
}
sorush-r
  • 10,490
  • 17
  • 89
  • 173

2 Answers2

0

Just use:

struct winsize w;
ioctl(0, TIOCGWINSZ, &w);

printf ("lines %d\n", w.ws_row);
printf ("columns %d\n", w.ws_col);
F.bernal
  • 2,594
  • 2
  • 22
  • 27
0

Print progress bar over the full width of the console by first getting console column width:

system("clear");

struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);

int barWidth = w.ws_col - 10;

float progress = 0.0;

while (progress < 1.0) {
    printf("\r%3d%% ", int(progress * 100.0));
    int pos = barWidth * progress;
    for (int i = 0; i < barWidth; i++) {
        if (i <= pos) printf("\u258A");
        else printf(" ");
    }
    fflush(stdout);

    progress += 0.02; // test

    usleep(100000);
}
printf("\r100%%\n");

column 80

column 20

column 123

rgos
  • 49
  • 5