【问题标题】:How to implement progress bars in C like apt-get?如何像apt-get一样在C中实现进度条?
【发布时间】:2023-01-16 21:46:29
【问题描述】:

我想使用 C 实现进度条,例如 Python 中的 tqdm 或 Ubuntu 中的 apt-get。但我不知道。

我的问题是如何让进度条一直在终端的底部,而顶部正常输出其他东西。

像Ubuntu中的apt-get程序是在下图中实现的。

【问题讨论】:

  • 这是通过特定于终端的字符序列完成的。它们通常被称为转义序列。您不想在没有库(例如 ncurses)的情况下实现它。终端如此之多,最好相信那些图书馆建设者为您所做的工作。
  • 对不起,我没有清楚地说明我的问题。我只想用c语言来达到这个效果。最好有一个库可以实现这种效果。谢谢你的 cmets。我将查看 ncurses 库。 @猎豹

标签: c linux progress-bar apt tqdm


【解决方案1】:

如果我知道您只是想在 apt 或 apt-get 代码中只查找进度条,以便稍后使用它,那么不能保证它被命名为 Progress:,或者包含 Progress 的提示:甚至在您正在搜索的脚本中。它可能来自另一个文件。

您可以尝试在 vim 或 kwrite 或 jot 等编辑器中打开脚本,并在脚本中查找调用 meter 的位置并从那里开始。不知道它是否会低于比例、米、百分比等...

在找不到任何东西的情况下,您总是可以使用一些简单的东西。网上有很多可用的。例子:

#!/bin/bash

## string of characters for meter (60 - good for 120 char width)
str='▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒'

tput civis                  # make cursor invisible

for i in `seq 1 100`; do    # for 1 to 100, save cursor, restore, output, restore
    printf "[s[u Progress: %s %3d %% [u" "${str:0:$(((i+1)/2))}" "$i"
    sleep 0.1               # small delay
done

printf "[K"             # clear to end-of-line

tput cnorm                  # restore cursor to normal

exit 0

【讨论】:

  • 谢谢您的回答!但我想知道如何使用C实现。或者有没有c库可以实现这种效果。 @Nasyx 拉基布
  • 您可以尝试使用 tqdm 库。你可以看看他们的源代码,看看它是如何实现的。我认为他们在这个主题中使用了最佳实践:github 上的 tqdm 请注意,还有其他 python 和其他语言的库,因此您也可以查看它们。
【解决方案2】:

我做成宏的形式,直接用。

#include <stdio.h>
#include <unistd.h>

#define START_PROGRESS_BAR(pbar, len) 
    char __##pbar[len] = {0};         
    memset(__##pbar, '#', sizeof(__##pbar) - 1)

#define PROGRESS_BAR_RUNING(pbar, per, fmt, ...) ({                                       
    float p = per >= 100.0 ? 100.0 : per;                                                 
    int left = (p / 100.0) * (sizeof(__##pbar) - 1);                                      
    int right = (sizeof(__##pbar) - 1) - left;                                            
    printf("
[%.*s%*s] %.0f%%" fmt, left, __##pbar, right, "", (float)per, __VA_ARGS__); 
})

int main(int argc, char const *argv[])
{
    START_PROGRESS_BAR(mybar, 64);

    for (int i = 0; i < 32; i++)
    {
        PROGRESS_BAR_RUNING(mybar, (float)i / 31 * 100.0, " %d KB/s", 105);
        usleep(100000);
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 2010-11-18
    • 2011-12-28
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    相关资源
    最近更新 更多