在研究这个问题时,在评论中我发现有人提到ANSI转义码来获得终端尺寸。由于我将使用ANSI转义序列,我认为这将是比ioctl()
或getenv()
更优雅的方式来获得终端大小。
这是一篇关于ioctl()的很好的文章,这是引起我兴趣的评论:
只是偶然发现了这个答案,当我意识到getenv("COLUMNS")在watch(1)下运行时完美地工作时,我的下巴掉了下来。因此,现在我有了一组回退,全部从TIOCWINSZ ioctl,到获取tenv(如果不是tty),到经典的ANSI转义"将光标移动到9999,9999和查询光标位置。最后一个适用于嵌入式系统的串行控制台:)
现在,我确实找到了一些关于ANSI的帖子(1,2),但没有一个回答我的具体问题-如何实际做到这一点?
使用这个图表,我推断为了将光标移动到最右和最下的位置,我需要CUP
(CSI n ; m H
) "光标位置"命令,这可能会翻译成类似x1b[9999;9999H
的东西。这是一个简单的部分,因为它是一个命令。
第二部分是我有一个大问题。即使我可以推断出我需要DSR
(CSI 6n
)"设备状态报告";命令,并且它去x1b[6n
,这个查询是如何工作的,即,我如何将数据存储在一个变量中,最好不中断在终端上显示的其他数据?
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <ctype.h>
#define SIZE 100
int main ( void) {
char in[SIZE] = "";
int each = 0;
int ch = 0;
int rows = 0;
int cols = 0;
struct termios original, changed;
// change terminal settings
tcgetattr( STDIN_FILENO, &original);
changed = original;
changed.c_lflag &= ~( ICANON | ECHO);
changed.c_cc[VMIN] = 1;
changed.c_cc[VTIME] = 0;
tcsetattr( STDIN_FILENO, TCSANOW, &changed);
printf ( "