【问题标题】:How to make console output fixed in place如何使控制台输出固定到位
【发布时间】:2016-09-07 06:58:07
【问题描述】:

My LAME (v3.99.5) 通过在控制台中向上移动 x 行并覆盖前面的行来输出控制台中的进度。挺好看的。

我在different post 中读到,仅使用"\r" 而不是"\n" 就可以实现单行的这种行为 - 尽管该帖子是针对 Ruby 的,但对于 C至少在我的系统上:

#include <stdio.h>
#include <time.h>

int main() {

    time_t t;
    time_t t2;

    time(&t);
    t2 = t;

    printf("%u\r", (unsigned int)t);        
    fflush(stdout);

    while (1) {
        if (t2 - t > 0) {
            time(&t);
            printf("%u\r", (unsigned int)t);        
            fflush(stdout);
        }
        time(&t2);
    }

    return 0;
}

该帖子进一步建议curses library 可用于使相同的行为多行。

C 中此类代码的样板示例是什么?

【问题讨论】:

    标签: c console curses


    【解决方案1】:

    根据http://falsinsoft.blogspot.com/2014/05/set-console-cursor-position-in-windows.html

    窗户:

    void SetCursorPos(int XPos, int YPos)
    {
        COORD Coord;
        Coord.X = XPos;
        Coord.Y = YPos;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Coord);
    }
    

    Linux:

    void SetCursorPos(int XPos, int YPos)
    {
        printf("\033[%d;%dH", YPos+1, XPos+1);
    }
    

    【讨论】:

      【解决方案2】:

      你可以这样使用:

      /!\ 警告:如果你之前没有调用endwin()就停止你的curses程序,用于启动程序的终端会有一个非常奇怪的行为。

      include <curses.h>
      
      int main(int argc, char *argv[]) 
      {
          // init curses
          Xinitscr(argc, argv); 
      
          // init time
          time_t t = 0, t2;
          time(&t2);
      
          // main loop
          while (1) {
              if (t2 - t > 0) 
              {
                  time(&t);
      
                  clear();
                  mvprintw(1,1, "%u", (unsigned int)t);
                  refresh();
              }
              time(&t2);
      
          }
      
          // end curses mode
          // warning: if you do not call this at the end of your program,
          // your terminal won't be usable.
          endwin();
      
          return 0;
      }
      

      【讨论】:

        【解决方案3】:

        @purplepsycho 显示的示例存在一些问题,已在本次修订中解决(适用于“任何”X/Open Curses 实现):

        #include <curses.h>
        
        int main(int argc, char *argv[]) 
        {
            filter();
            initscr();
        
            // init time
            time_t t = 0, t2;
            time(&t2);
        
            // main loop
            while (1) {
                if (t2 - t > 0) 
                {
                    time(&t);
        
                    erase();
                    mvprintw(1,1, "%u", (unsigned int)t);
                    refresh();
                }
                time(&t2);
        
            }
            endwin();
        
            return 0;
        }
        

        即:

        • 使用initscr 初始化curses(PDCurses 提供了一个非标准函数Xinitscr,这不是 OP 所考虑的:它肯定不经常使用)。
        • 使用erase 而不是clear(以避免屏幕闪烁):

          clearwclear 例程类似于 erasewerase, 但是他们也调用clearok,这样屏幕就清空了 完全在下一次调用该窗口的 wrefresh 并从头开始重新粉刷。

        • 使用filter 将输出保持在一行。
          如果您的终端切换到备用屏幕,屏幕将显示为已清除。有一个可用于 ncurses 的解决方法(请参阅 ncurses-examples 中的 filter.c)。

        erase() 更好的是wclrtoeol(),在mvprintw 之后调用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-21
          • 1970-01-01
          • 1970-01-01
          • 2013-11-14
          相关资源
          最近更新 更多