为什么termcaps在“ write”系统调用之前不起作用?

问题描述

为什么该程序的输出未加下划线

int main() {
  tgetent(NULL,getenv("TERM"));
  tputs(tgetstr("us",NULL),1,&putchar);
  write(1,"Hello World!\n",13);
  tputs(tgetstr("ue",&putchar);
}

但是这个吗?

int main() {
  tgetent(NULL,&putchar);
  puts("Hello World!");
  tputs(tgetstr("ue",&putchar);
}

编辑

问题的确与缓冲区管理有关!如果我添加fflush,则该字符串会正确加下划线

int main() {
  tgetent(NULL,&putchar);
  fflush(stdout);
  write(1,&putchar);
}

解决方法

差异的原因是putcharputs缓冲,而write不是。在这个例子中

int main() {
  tgetent(NULL,getenv("TERM"));
  tputs(tgetstr("us",NULL),1,&putchar);
  write(1,"Hello world!\n",13);
  tputs(tgetstr("ue",&putchar);
}

写的字符

write(1,13);

可能首先进入屏幕,因为(不同于tputs调用)它们是立即写入的。 tputs调用编写的字符存储在缓冲区中(通常比tgetstr返回的字符串大 ),因为您没有提供其他刷新方法缓冲区,这些缓冲区是在运行时退出时由运行时的清理写入的。

在没有显式return语句的情况下,C标准保证它具有与调用exit(在每个打开的文件(包括诸如 stdout等流)上执行fflush的效果相同)的作用。 em>)。

虽然您原则上可以构造一个具有极长字符串的termcap,但应该将termcap描述限制为1023个字节(甚至terminfo描述通常限制为4096个字节),而标准I / O缓冲区的大小通常为是该限制的几倍,因此您在没有很多的工作(即更改运行时间...)的情况下不会看到那些tputs的呼叫被写出。