gpt4 book ai didi

c - 为什么这段代码可以在应该为空的时候从 stdin 中读取?

转载 作者:行者123 更新时间:2023-12-04 09:25:29 26 4
gpt4 key购买 nike

代码来自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 行,但我无法理解其中的操作:

  1. 为什么输出第2行的那些字符?因为 write() 函数已经向 STDOUT 写入了一些字符?如果是,我该如何抑制此输出?

  2. 为什么 read() 函数可以从 STDIN 读取一些东西?我只是觉得 STDIN 现在应该是空的,因为我没有按下任何键。

  3. 在第 2 行之后,它将阻塞。为什么我必须按 ENTER

  4. 为什么第 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 会有所作为。

write() 之前使用 stty() 系统调用将终端设置为原始模式应该可以防止此输出以及对 ENTER 键的需要。如果您更改终端模式,也就是线路规则,请记住保存当前设置并在退出程序之前恢复它们。

关于c - 为什么这段代码可以在应该为空的时候从 stdin 中读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38400407/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com