为什么不';termcaps在'write'系统调用之前工作吗?
为什么这个程序的输出没有下划线为什么不';termcaps在'write'系统调用之前工作吗?,c,unix,terminal,termcap,C,Unix,Terminal,Termcap,为什么这个程序的输出没有下划线 int main() { tgetent(NULL, getenv("TERM")); tputs(tgetstr("us", NULL), 1, &putchar); write(1, "Hello world!\n", 13); tputs(tgetstr("ue", NULL), 1, &putchar); } int main() { tg
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
write(1, "Hello world!\n", 13);
tputs(tgetstr("ue", NULL), 1, &putchar);
}
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
fflush(stdout);
write(1, "Hello world!\n", 13);
tputs(tgetstr("ue", NULL), 1, &putchar);
}
但是这个是
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
puts("Hello world!");
tputs(tgetstr("ue", NULL), 1, &putchar);
}
编辑
事实上,问题在于缓冲区管理!如果我添加fflush
,字符串将正确加下划线
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
write(1, "Hello world!\n", 13);
tputs(tgetstr("ue", NULL), 1, &putchar);
}
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
fflush(stdout);
write(1, "Hello world!\n", 13);
tputs(tgetstr("ue", NULL), 1, &putchar);
}
产生差异的原因是
putchar
和put
是缓冲的,而write
不是。在这个例子中
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
write(1, "Hello world!\n", 13);
tputs(tgetstr("ue", NULL), 1, &putchar);
}
作者所写的人物
write(1, "Hello world!\n", 13);
可能首先进入屏幕,因为(与tputs
调用不同)它们是立即写入的。由tputs
调用写入的字符存储在缓冲区中(通常比从tgetstr
返回的字符串大很多),并且由于您没有提供刷新缓冲区的其他方法,因此这些字符在运行时退出时由运行时的清理程序写入
如果没有显式的return语句,C标准保证它与调用exit
(它对每个打开的文件(包括stdout等流)执行fflush
)具有相同的效果
虽然原则上您可以构造具有超长字符串的termcap,但termcap描述应限制为1023字节(甚至terminfo描述通常也限制为4096字节),而标准I/O缓冲区大小通常是该限制的几倍,因此,如果没有大量的工作(即更改运行时…),您就不会看到那些
tput
调用被写出来。,因为termcap/ternfo假设它完全控制显示,而write()
会破坏这一点。您必须refresh()
才能放置termcap/terminfo信息。如果你运气好的话,write()
可能会工作。但是您不应该将termcap/ternfo函数与低级的write()
(或read()
)函数混合使用。@JonathanLeffler谢谢!但是write()
与像putchar()
和put()
这样的“高级”函数有何不同?除了缓冲区管理?嗯……我很想说“这都是关于缓冲区管理的”,但这是假设诅咒
,而不仅仅是termcap
或termfo
。然后我做噩梦…。然后我查看了手册页(Mac上的man3tput
),它们毕竟是curses
的一部分,因此很可能都是关于缓冲区管理的。您还没有显示MCVE(-或MRE或现在使用的任何名称)或SSCCE()。程序中还有什么?问题确实与缓冲区管理有关!感谢您的帮助:)问题确实是
请将此作为您问题的答案发布。