【发布时间】:2016-11-18 22:01:24
【问题描述】:
代码来自 Kilo 项目:
/*
* Use write() and terminal escape (ESC) sequence
* to query cursor position.
*/
#include <stdio.h>
#include <unistd.h>
#define ESC 27
int main(int argc, char const *argv[]) {
char buf[32];
unsigned int i = 0;
int rows, cols;
write(STDOUT_FILENO, "\033[6n", 4);
while (i < sizeof(buf)-1) {
if (read(STDIN_FILENO,buf+i,1) != 1) break;
if (buf[i] == 'R') break;
i++;
}
buf[i] = '\0';
/* Parse it. */
if (buf[0] != ESC || buf[1] != '[') return -1;
if (sscanf(buf+2,"%d;%d",&rows,&cols) != 2) return -1;
printf("%d %d\n", rows, cols);
return 0;
}
OS X terminal.app 中的结果是:
➜ /Users/name/Desktop/demo ./write
^[[44;1R
44 1
➜ /Users/name/Desktop/demo
➜ /Users/name/Desktop/demo
结果有 5 行,但我无法理解动作:
为什么它会在第 2 行输出这些字符?因为
write()函数向STDOUT写入了一些字符?如果是,我该如何抑制这个输出?为什么
read()函数可以从STDIN中读取内容?我只是觉得STDIN现在应该是空的,因为我没有按任何键。在第 2 行之后,它将阻塞。为什么我必须按 ENTER?
为什么第 4 行是空的?是因为我刚刚按下了ENTER?
在 OS X 10.11.6 Terminal.app 中运行
【问题讨论】:
-
^[[是一个终端控制序列。例如“将光标移动到位置 x,y”,或“将文本颜色更改为红色”。 -
是的,我知道控制序列的功能。但为什么它可以从 STDIN 读取?
-
read函数将阻塞,直到有内容可供阅读。按下回车键后,该行将发送到您的程序以便它可以读取。 -
@user3121023 所以你的意思是转义码的结果将显示在STDIN然后read()可以从STDIN读取光标位置?如果是,如何抑制第 2 行输出?