我目前正在开发一个程序,该程序在启动时呈现一个绿色方块。该程序允许用户通过键入“d”将方块向右移动两个空格,而无需额外的 Enter 和回显。要恢复用户需要键入字符后按 Enter 且终端回显的原始模式,用户应键入“]”而不需要额外的 Enter。然而,当我对此进行测试时,程序并没有按预期恢复到原始模式。这是代码
struct termios orig_termios;
void clear_screen()
{
printf("\033[H\033[J\033[?25l");
fflush(stdout);
}
void green_square()
{
printf("\033[42m \033[0m");
}
void move_cursor(int hx, int hy)
{
printf("\033[%d;%dH", hy, hx);
fflush(stdout);
}
void disableRawMode()
{
tcsetattr(0, TCSAFLUSH, &orig_termios);
}
void enableRawMode()
{
tcgetattr(0, &orig_termios);
atexit(disableRawMode);
struct termios raw = orig_termios;
raw.c_lflag &= ~(ECHO | ICANON);
tcsetattr(0, TCSAFLUSH, &raw);
}
int main()
{
int x = 1; // starting position of the green square
int y = 1;
enableRawMode();
while (1)
{
clear_screen();
move_cursor(x, y);
green_square();
char c = getchar();
if (c == 'd')
{
x += 2; // move right 2 spaces
}
else if (c == ']')
{
disableRawMode();
exit(0);
}
usleep(10000); // wait for 100 milliseconds
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用 gcc 编译了代码。我跑过去了./a.out。当我用“]”终止它时,终端的光标保持不可见的状态。
我也试过了tcsetattr(0, TCSANOW, &orig_termios);也不行。
我如何解决它
我存储了属性并尝试恢复终端设置,但程序没有恢复到原始模式。我该怎么做?
您在评论中澄清说,您的意思是输入光标在程序终止后仍然不可见。当然是这样,因为您只恢复终端属性,而光标状态不属于这些属性(如果终端甚至支持光标)。终端属性几乎都是关于与终端设备之间的数据传输的特性。
此外,程序并不是通过设置终端属性来首先关闭光标的。相反,它通过在每次调用 期间向终端发送一个用于该目的的 ANSI 转义序列* ( )来关闭光标。因此,如果您希望程序在终止之前打开光标,那么它应该发送相应的 ANSI 序列:。\033[?25lclear_screen()\033[?25h
另请注意,如果程序无法做到这一点——例如,如果它是通过 Ctrl-C 而不是通过键入“]”终止的——那么您应该能够通过reset在终端。
*对于某些 DEC 终端品种 - 它位于指定给制造商使用的“私有”代码范围内,因此它可能会执行不同的操作或对其他终端没有任何影响。
| 归档时间: |
|
| 查看次数: |
68 次 |
| 最近记录: |