C 如何更新终端中的值

C 如何更新终端中的值,c,C,有像ddrescue这样的linux终端程序,不管当前行的位置如何,都会更新终端输出 意味着当前终端输出可能已经包含了一些命令行 您运行ddrescue,它会以Kb/秒的速度更新当前的I/O位置,在最新版本中,更新自身也需要经过一段时间。值已更新,但屏幕上已打印的内容仍保留在屏幕上 所有这些值都在更新,没有任何由新行组成的屏幕填充和任何类型的向上滚动,事实上,终端向上滚动条。。。不收缩:-) 问题是Linux下的ANSIC特定,因为DDFEXT是用C++编写的,而我希望能够以类似的方式输出,但是

有像ddrescue这样的linux终端程序,不管当前行的位置如何,都会更新终端输出

意味着当前终端输出可能已经包含了一些命令行

您运行ddrescue,它会以Kb/秒的速度更新当前的I/O位置,在最新版本中,更新自身也需要经过一段时间。值已更新,但屏幕上已打印的内容仍保留在屏幕上

所有这些值都在更新,没有任何由新行组成的屏幕填充和任何类型的向上滚动,事实上,终端向上滚动条。。。不收缩:-)

问题是Linux下的ANSIC特定,因为DDFEXT是用C++编写的,而我希望能够以类似的方式输出,但是在C.


如果您有任何将使用gcc linux编译的示例代码,谢谢(例如,一个时钟将出现在当前行上,并在该确切位置进行自我更新)

终端查找支持颜色、光标定位、粗体显示的转义序列(某些字节模式),等。程序挂接到那些更新屏幕而不滚动

它不是特定于C语言的,它内置于终端(窗口终端仿真器)中。任何向终端发送输出的东西都可以做到这一点。检查课程图书馆;ncuses基础和ncurses文档

例如,下面是一个tcsh shell命令,它将您的窗口标题设置为window:

echo -n "\e]0;WINDOW\a"
其中,
\e
是ESC字符(^[,0x1B),
\a
是BEL(报警,^G,0x07)


编辑:好的,这在tcsh中有效,但在sh或bash中不起作用。

这里有一个快速破解,显示了使用ANSI转义生成类似于
wget
进度条的行为。可以进行额外的约束检查调整,但这只是一个简单的示例。重复调用
progress
会生成一个给定电流的进度条t值
n
在终端宽度
sz
中的总计
t
(当前限制为70个字符)。完成对
progress的调用时,清除保留在行上的所有字符。(或者只需打印
换行
,将完成的仪表保留在行上)

虽然转义码的可用性取决于终端,但在支持转义的终端中,
\033[s
保存光标位置)和
\033[u
恢复保存位置)是相当普遍的选择

有许多方法可以处理从
printf
fieldwidths
padding
memcpy
的格式设置,以填充字符数组。这说明了使用转义符控制行上的输出以提供仪表的原理:

#include <stdio.h>
#include <unistd.h>     /* for usleep */

#define MAXPM 120

/* progress meter called with current increment 'n' of a 
total number of increments 't' fit into a maximum terminal
width of 'sz'. (< MAXPM) It should be called and updated
without intervening output to stdout.
*/
static inline void progress (int n, int t, int sz)
{
    int pct =  (n * 100) / t;
    char mkr[] = { [0 ... MAXPM] = '=', [MAXPM+1] = 0 };
    char spc[] = { [0 ... MAXPM] = ' ', [MAXPM+1] = 0 };
    int nmkr = (pct * sz) / 100;
    int nspc = sz - nmkr;

    mkr[nmkr] = 0;      /* terminate at appropriate size */
    spc[nspc] = 0;

    printf ("\033[s\033[u %3d %% [%s%s]\033[u", pct, mkr, spc);
    fflush (stdout);    /* required due to no newline   */
}

/* simple clear to end of line - if desired, otherwise, just print newline */
void progress_clear ()
{ printf ("\033[K"); fflush (stdout); }

int main () {

    int i = 0;

    for (i = 0; i <= 50; i++) {
        /* do something that returns progress */
        progress (i, 50, 70);
        usleep (100000);
    }
    // progress_clear ();  /* clean up - remove meter (if wanted) */
    printf ("\n");

    return 0;
}

感谢您提供的任何提示和/或框架。您可能会发现ncurses库很有趣。抱歉,dandan78,我发现您的编辑没有帮助,需要Linux中的ANSI C规范,否则谁会阅读,他如何理解我们正在讨论的终端?谁会知道C如何对阅读本文感兴趣?此编辑可能会导致愚蠢的回答。
$ ./bin/progbar
   0 % [                                                                      ]
   2 % [=                                                                     ]
   4 % [==                                                                    ]
   6 % [====                                                                  ]
(snip)
  94 % [=================================================================     ]
  96 % [===================================================================   ]
  98 % [====================================================================  ]
 100 % [======================================================================]