代码之家  ›  专栏  ›  技术社区  ›  kolrie

控制台进度指示器

  •  7
  • kolrie  · 技术社区  · 16 年前

    对于正在执行的任务,实现基于控制台的进度指示器是一种简单的方法,但是我无法预测它将花费多少时间?

    我以前在用clipper编码的时候就这么做了,这只不过是遍历字符'/'、'-'、'\'、''并将它们定位在同一位置的问题。

    任何方式/链接/ LIB做这(或类似的东西)在C++中?

    其目标是*nix环境。

    编辑:

    • 将标题改为更连贯和通用的标题;
    • 添加了目标环境。
    4 回复  |  直到 16 年前
        1
  •  24
  •   Zan Lynx    16 年前

    一个非常简单的方法是打印出一个字符串,后跟一个 '\r' 性格。这就是回车本身,在大多数控制台上,它将光标返回到行首而不向下移动。这允许您覆盖当前行。

    如果您正在写入stdout、cout或clog,请记住fflush或std::flush流,使其立即输出行。如果您正在写入stderr或cerr,那么流是无缓冲的,所有输出都是即时的(并且效率低下)。

    要做到这一点,一个更复杂的方法是像诅咒一样使用屏幕绘制库。Windows控制台还有其他一些设置直接屏幕写入的方法,但我不知道它们是什么。

        2
  •  10
  •   D.Shawley    16 年前

    您可以尝试如下操作:

    void
    spinner(int spin_seconds) {
        static char const spin_chars[] = "/-\\|";
        unsigned long i, num_iterations = (spin_seconds * 10);
        for (i=0; i<num_iterations; ++i) {
            putchar(spin_chars[i % sizeof(spin_chars)]);
            fflush(stdout);
            usleep(100000);
            putchar('\b');
        }
    }
    

    当然,这是不标准的,因为次秒 usleep() 我不确定是否有任何保证 \b 是否擦除字符,但它在大多数平台上都有效。你也可以试试 \r 相反,如果 \b 不玩这个把戏。否则,请尝试查找 curses .

    编辑(诅咒示例)

    这应该让你开始:

    #include <curses.h>
    #include <unistd.h>
    
    void spinner(int spin_seconds) {
        static char const spin_chars[] = "/-\\|";
        unsigned long i, num_iterations = (spin_seconds * 10);
        for (i=0; i<num_iterations; ++i) {
            mvaddch(0, 0, spin_chars[i & 3]);
            refresh();
            usleep(100000);
        }
    }
    
    int main() {
        initscr();    /* initializes curses */
        spinner(10);  /* spin for 10 seconds */
        endwin();     /* cleanup curses */
        return 0;
    }
    

    确保链接到 -lcurses -lncurses . 这在任何一个Unix上都可以工作。

        3
  •  2
  •   user182582    16 年前

    Boost有一个进度库,可以帮助一些事情

        4
  •  1
  •   DigitalRoss    16 年前

    真的, clipper ,也许你是在谈论@row,col语言内置的东西?(仅限反问句…)

    您可以使用printf执行简单的进度条:您可以省去后面的换行符。为了套印字符,可以用\b开始或结束字符串。这样做很容易做到传统的那种。

    我记得EclipseUI指南推荐了进度指示器,不管您对实际进度了解多少。我认为理论上任何事都比什么都好,只要尽你所能。

    您可能需要的唯一技巧是潜在地击败线路缓冲。一定要 fflush(stdout) 每次输出操作后。(或ostream::flush())