如何在不使用字符的情况下使用termcap在C程序中获取光标位置? [英] How to get the cursor position in a C program using termcap, without writing a character?
问题描述
我想知道如何在程序中获得光标位置(x,y),而无需在屏幕上写任何东西,也不能一直跟踪它.
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, "\033[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++;
}
}
此功能为我提供了准确的光标位置(*行= y,* col = x),但它在屏幕上书写.
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 writting anything on the screen ? (because if the cursor is on one of the printed characters, it will overwrite it).
这是一个学校项目,所以我只能使用termcap,不能使用ncurses函数,唯一允许的函数是tputs,tgoto,tgetstr,tgetnum,tgetflag.
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.
推荐答案
有几个问题:
-
规范模式为缓冲(请参见下文)
read
在用于标准输出的文件描述符上完成(可能会起作用—有时—但不要指望它)
the read
is done on the file-descriptor for standard output (that may happen to work — sometimes — but don't count on it)
read
读取的字符不足以获得典型的响应
the read
does not read enough characters to get a typical response
响应将有两个十进制整数,以分号 ;
the response would have two decimal integers, separated by semicolon ;
响应将带有最后一个字符(如果read
实际要求提供足够的字符,这将成为问题……)
the response would have a final character (which would become an issue if the read
actually asked for enough characters...)
进一步阅读:
- 常规终端接口 单个UNIX ®规范,版本2
在规范模式输入处理中,终端输入以行为单位进行处理.行由换行符(
NL
),文件结束符(EOF
)或行结束符(EOL
)分隔.有关EOF
和EOL
的更多信息,请参见特殊字符.这意味着read
请求将不返回,直到键入了整行或收到信号为止.同样,无论在read()调用中请求多少个字节,最多都将返回一行.但是,不必一次读取整行.可以在read()中请求任意数量的字节,甚至一个字节,而不会丢失信息.
In canonical mode input processing, terminal input is processed in units of lines. A line is delimited by a newline character (
NL
), an end-of-file character (EOF
), or an end-of-line (EOL
) character. See Special Characters for more information onEOF
andEOL
. This means that aread
request will not return until an entire line has been typed or a signal has been received. Also, no matter how many bytes are requested in the read() call, at most one line will be returned. It is not, however, necessary to read a whole line at once; any number of bytes, even one, may be requested in a read() without losing information.
- XTerm控制序列
- XTerm Control Sequences
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
也就是说,您的程序应该准备读取 Escape [
,后跟两个十进制整数(其长度没有固定限制),以及另外两个字符;
和R
.
That is, your program should be prepared to read Escape[
followed by two decimal integers (with no fixed limit on their length), and two other characters ;
and R
.
顺便说一句, termcap 本身对您的解决方案无济于事.尽管ncurses在终端数据库中定义了一些相关功能:
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)
很少有程序使用它们,在任何情况下,您都会发现很难在termcap应用程序中使用光标位置报告.
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程序中获取光标位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!