当前位置:  开发笔记 > 编程语言 > 正文

如何在C中覆盖stdout

如何解决《如何在C中覆盖stdout》经验,为你挑选了4个好方法。

在大多数现代shell中,您可以点击向上和向下箭头,它会在提示符下放置您执行的先前命令.我的问题是,这是如何工作的?!

在我看来,shell以某种方式操纵stdout来覆盖它已经编写的内容?

我注意到像wget这样的程序也可以这样做.有人知道他们是怎么做到的吗?



1> ephemient..:

它不是在操纵标准输出 - 它会覆盖已经由终端显示的字符.

试试这个:

#include 
#include 
static char bar[] = "======================================="
                    "======================================>";
int main() {
    int i;
    for (i = 77; i >= 0; i--) {
        printf("[%s]\r", &bar[i]);
        fflush(stdout);
        sleep(1);
    }
    printf("\n");
    return 0;
}

这非常接近wget输出,对吗? \r是一个回车符,终端将其解释为"将光标移回当前行的开头".

您的shell(如果是bash)使用GNU Readline库,它提供了更多通用功能,包括检测终端类型,历史管理,可编程键绑定等.

还有一件事 - 如果有疑问,你的wget,你的shell等的来源都是可用的.



2> vladr..:

要覆盖当前标准输出行(或其中的一部分),请使用\r(或\b.)特殊字符\r(回车符)将把插入符号返回到行的开头,允许您覆盖它.特殊字符\b只会使插入符号返回一个位置,允许您覆盖最后一个字符,例如

#include 
#include 

int i;
const char progress[] = "|/-\\";

for (i = 0; i < 100; i += 10) {
  printf("Processing: %3d%%\r",i); /* \r returns the caret to the line start */
  fflush(stdout);
  sleep(1);
}
printf("\n"); /* goes to the next line */
fflush(stdout);

printf("Processing: ");
for (i = 0; i < 100; i += 10) {
  printf("%c\b", progress[(i/10)%sizeof(progress)]); /* \b goes one back */
  fflush(stdout);
  sleep(1);
}
printf("\n"); /* goes to the next line */
fflush(stdout);

使用fflush(stdout);是因为标准输出通常是缓冲的,否则信息不会立即打印在输出或终端上


可能要为睡眠功能添加#include .

3> SoapBox..:

除了\ r和\ b之外,还可以看看ncurses对控制台屏幕上的内容进行一些高级控制.(包括列,任意移动等).



4> sleske..:

在文本终端/控制台中运行的程序可以以各种方式操作其控制台中显示的文本(使文本变为粗体,移动光标,清除屏幕等).这是通过打印称为"转义序列"的特殊字符序列来实现的(因为它们通常以Escape,ASCII 27开头).

如果stdout进入了解这些转义序列的终端,则终端的显示将相应地改变.

如果将stdout重定向到文件,则转义序列将出现在文件中(通常不是您想要的).

转义序列没有完整的标准,但大多数终端使用VT100引入的序列,有许多扩展.这就是Unix/Linux下的大多数终端(xterm,rxvt,konsole)和其他像PuTTY这样的终端.

在实践中,您不会直接将转义序列硬编码到您的软件中(尽管您可以),但是使用库来打印它们,例如上面提到的ncurses或GNU readline.这允许与不同终端类型兼容.

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有