Wit*_*iko 8 c terminal ncurses xterm ansi-escape
我正在尝试使用以下代码检索VT100终端中光标的坐标:
void getCursor(int* x, int* y) {
printf("\033[6n");
scanf("\033[%d;%dR", x, y);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用以下ANSI转义序列:
设备状态报告 - ESC [6n
将光标位置报告给应用程序(就像键入键盘一样)ESC [n; mR,其中n是行,m是列.
代码编译并发送ANSI序列,但是,在接收到它之后,终端将^[[x;yR字符串打印到stdout而不是stdin使我无法从程序中检索它:

显然,字符串是为程序指定的,所以我必须做错误的事情.有人知道它是什么吗?
小智 6
我要求光标位置。如果我在 100 毫秒后没有答案(这是任意的),我想控制台不是 ansi。
/* This function tries to get the position of the cursor on the terminal.
It can also be used to detect if the terminal is ANSI.
Return 1 in case of success, 0 otherwise.*/
int console_try_to_get_cursor_position(int* x, int *y)
{
fd_set readset;
int success = 0;
struct timeval time;
struct termios term, initial_term;
/*We store the actual properties of the input console and set it as:
no buffered (~ICANON): avoid blocking
no echoing (~ECHO): do not display the result on the console*/
tcgetattr(STDIN_FILENO, &initial_term);
term = initial_term;
term.c_lflag &=~ICANON;
term.c_lflag &=~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
//We request position
print_escape_command("6n");
fflush(stdout);
//We wait 100ms for a terminal answer
FD_ZERO(&readset);
FD_SET(STDIN_FILENO, &readset);
time.tv_sec = 0;
time.tv_usec = 100000;
//If it success we try to read the cursor value
if (select(STDIN_FILENO + 1, &readset, NULL, NULL, &time) == 1)
if (scanf("\033[%d;%dR", x, y) == 2) success = 1;
//We set back the properties of the terminal
tcsetattr(STDIN_FILENO, TCSADRAIN, &initial_term);
return success;
}
Run Code Online (Sandbox Code Playgroud)
您的程序正在运行,但正在等待 EOL 字符。
scanf是面向行的,因此它在处理之前等待新行。尝试运行您的程序,然后按 Enter 键。
解决方案是使用其他不需要换行的东西来读取输入,然后使用 sscanf 解析出值。
您还需要使标准输入非阻塞,否则在缓冲区已满或标准输入关闭之前您将无法获得输入。看到这个问题Making stdin non-blocking
您还应该fflush(stdout);在 printf 之后调用以确保它确实被写入(printf 通常是行缓冲的,因此如果没有换行符,它可能不会刷新缓冲区)。
| 归档时间: |
|
| 查看次数: |
2507 次 |
| 最近记录: |