mer*_*ito 2 c io macos terminal
代码来自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;
}
Run Code Online (Sandbox Code Playgroud)
OS X terminal.app的结果是:
? /Users/name/Desktop/demo ./write
^[[44;1R
44 1
? /Users/name/Desktop/demo
? /Users/name/Desktop/demo
Run Code Online (Sandbox Code Playgroud)
结果有5行,但我无法理解这些行为:
为什么在第2行输出这些字符?因为write()函数已经写了一些字符STDOUT?如果是,我该如何抑制此输出?
为什么read()函数可以从中读取内容STDIN?我认为STDIN现在应该是空的,因为我没有按任何键.
在第2行之后,它将阻止.我为什么要按ENTER?
为什么第4行是空的?因为ENTER我刚刚按下了吗?
在OS X 10.11.6 Terminal.app中运行
转义序列\e[6n用于向终端查询光标位置.终端通过输入字符来回答,好像它们是由用户键入的一样.答案格式是\e[y;xR其中y的行数和x列数,两者1为主.这里\e[44;1R是终端在线模式下回显的,就像任何其他用户输入一样.请注意,转义字节的回显为^[.您可以使用退格键编辑此输出.尝试通过更改列号来修改列号,^[[44;11R并在按ENTER时查看效果.
程序尝试读取此输入但由于终端处于线路模式,您需要输入ENTER键以输入整行输入以供系统使用.
请注意,程序通过单个read()系统调用逐字节地从系统读取此输入.它在获取时停止读取R,因此换行保留在系统缓冲区中.
程序sscanf()解析\e[44;1,打印44 1(第44行,第1列)并退出.
shell回显命令提示符,读取待处理的换行符并回显另一个命令提示符.
我不知道如何抑制line2输出.我怀疑重定向stdout会有所作为.
使用stty()系统调用将终端设置为原始模式之前write()应该阻止此输出以及需要输入ENTER键.如果您更改终端模式,即线路规则,请记住保存当前设置并在退出程序之前恢复它们.
| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |