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