控制台

时间:2017-01-04 10:22:42

标签: c linux unix terminal console

我在为计算工具添加进度条时遇到问题(用c编写)。有一个简单的进度条形码,我可以打印进度:

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);
}

虽然,它只打印一个固定宽度的进度条。如何更改此选项以读取屏幕宽度并打印全宽进度条? (例如wgetapt-get进度条)

更新

到目前为止我尝试使用ioctl读取终端宽度:

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

而且我也不想添加像ncurses ...

这样的依赖项

更新2

最终(不工作)版本:

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);
}

2 个答案:

答案 0 :(得分:0)

只需使用

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

printf ("lines %d\n", w.ws_row);
printf ("columns %d\n", w.ws_col);

答案 1 :(得分:0)

首先获取控制台列宽,在控制台的整个宽度上打印进度条:

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