问题描述
我想知道如何在我的程序中获取光标位置 (x, y),而不在屏幕上写任何东西,也不会一直跟踪它.
我找到了一种使用此函数获取其位置的方法(我在这里不检查读取、写入等的返回来编写有关此主题的较小代码,但我在我的程序中这样做):
void get_cursor_position(int *col, int *rows){int a = 0;int i = 0;字符缓冲区[4];写(1,33[6n",4);//请求光标位置的字符串读(1,缓冲区,4);而 (buf[i]){如果 (buf[i] >= 48 && buf[i] <= 57){如果 (a == 0)*rows = atoi(&buf[i]) - 1;别的*col = atoi(&buf[i]) - 1;一个++;}我++;}}
这个函数给了我准确的光标位置(*rows = y,*col = x),但它写在屏幕上.
如何在屏幕上不写任何东西的情况下获取光标位置?
(如果光标在打印的字符之一上,它将覆盖它.)
应该在发送转义序列之前和之后切换 echo 吗?
这是一个学校项目,所以我只能用termcap,不能用ncurses函数,唯一允许的函数是tputs、tgoto、tgetstr、tgetnum、tgetflag.
有几个问题:
规范模式是缓冲(见下文)
read
是在标准输出的文件描述符上完成的(这可能碰巧工作—有时—但不要指望它)read
没有读取足够的字符来获得典型的响应响应将有两个十进制整数,用分号分隔
;
响应将有一个最终字符(如果
read
实际上要求足够的字符,这将成为一个问题...)
进一步阅读:
- 通用终端界面 单一的 UNIX® 规范,第 2 版
在规范模式输入处理中,终端输入以行为单位进行处理.一行由换行符 (NL
)、文件结束符 (EOF
) 或行结束符 (EOL
) 字符.有关 EOF
和 EOL
的更多信息,请参阅特殊字符.这意味着 read
请求将不返回,直到输入整行或接收到信号.此外,无论在 read() 调用中请求多少字节,最多返回一行.然而,没有必要一次阅读整行;可以在 read() 中请求任意数量的字节,甚至是一个字节,而不会丢失信息.
也就是说,你的程序应该准备好读取后跟两个十进制整数(长度没有固定限制),以及另外两个字符 ;
和 R
.
顺便说一下,termcap 本身对您的解决方案几乎没有帮助.虽然 ncurses 在终端数据库中定义了一些相关功能:
# u9 终端查询字符串(相当于 ANSI/ECMA-48 DA)# u8 终端应答描述# u7 光标位置请求(相当于 VT100/ANSI/ECMA-48 DSR 6)# u6 光标位置报告(相当于 ANSI/ECMA-48 CPR)
很少有程序使用这些,而且无论如何您都会发现在 termcap 应用程序中使用光标位置报告很困难.
I would like to know how to get the cursor position (x, y) in my program, without writing anything on the screen neither tracking it all the time.
I found out a way to get its position with this function (I don't check the return of read, write, etc here to write a smaller code on this subject but I do it in my program):
void get_cursor_position(int *col, int *rows)
{
int a = 0;
int i = 0;
char buf[4];
write(1, "33[6n", 4); // string asking for the cursor position
read(1, buf, 4);
while (buf[i])
{
if (buf[i] >= 48 && buf[i] <= 57)
{
if (a == 0)
*rows = atoi(&buf[i]) - 1;
else
*col = atoi(&buf[i]) - 1;
a++;
}
i++;
}
}
This function gives me the exact cursor position (*rows = y, *col = x), but it writes on the screen.
How can I get the cursor position without writing anything on the screen?
(If the cursor is on one of the printed characters, it will overwrite it.)
Should echo be toggled before and after sending the escape sequence?
This is a school project, so I only can use termcap, I can't use ncurses functions, the only allowed functions are tputs, tgoto, tgetstr, tgetnum, tgetflag.
There are several problems:
canonical mode is buffered (see below)
the
read
is done on the file-descriptor for standard output (that may happen to work — sometimes — but don't count on it)the
read
does not read enough characters to get a typical responsethe response would have two decimal integers, separated by semicolon
;
the response would have a final character (which would become an issue if the
read
actually asked for enough characters...)
Further reading:
- General Terminal Interface The Single UNIX ® Specification, Version 2
CSI Ps n Device Status Report (DSR). Ps = 5 -> Status Report. Result ("OK") is CSI 0 n Ps = 6 -> Report Cursor Position (CPR) [row;column]. Result is CSI r ; c R
That is, your program should be prepared to read followed by two decimal integers (with no fixed limit on their length), and two other characters ;
and R
.
By the way, termcap by itself will do little for your solution. While ncurses has some relevant capabilities defined in the terminal database:
# u9 terminal enquire string (equiv. to ANSI/ECMA-48 DA)
# u8 terminal answerback description
# u7 cursor position request (equiv. to VT100/ANSI/ECMA-48 DSR 6)
# u6 cursor position report (equiv. to ANSI/ECMA-48 CPR)
few programs use those, and in any case you would find it difficult to use the cursor position report in a termcap application.
这篇关于如何使用termcap获取C程序中的光标位置,而不写字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!