gpt4 book ai didi

c - 在curses 模式之外使用getch 的可移植性如何?

转载 作者:行者123 更新时间:2023-12-02 08:11:21 25 4
gpt4 key购买 nike

我正在开发一个终端程序来识别各个按键,包括键盘按键,但如果可能的话,我不想在诅咒/程序模式下进行。我想我可能只是利用诅咒并使用 tcgetattr() 和 tcsetattr() ,而不是使用 terminfo 和某种映射或树结构来进行快速键盘按键匹配来重新发明轮子。 > 在curses 模式之外做我想做的事情,同时仍然使用curses I/O 函数为我翻译键盘按键。令我惊讶的是,这有效(Linux,ncurses 6.1.20180127):

/**
* Most error checking elided for brevity.
*/
#include <stdio.h> // printf
#include <string.h> // memcpy

#include <curses.h>
#include <termios.h> // tcgetattr, tcsetattr

int main(void)
{
struct termios curr, new_shell_mode;
int c, fd;
SCREEN *sp;
FILE *ttyf;

/*
* Initialize desired abilities in curses.
* This unfortunately clears the screen, so
* a refresh() is required, followed by
* endwin().
*/
ttyf = fopen("/dev/tty", "r+b");
fd = fileno(ttyf);
sp = newterm(NULL, ttyf, ttyf);
raw();
noecho();
nonl();
keypad(stdscr, TRUE);
refresh();
// Save the current curses mode TTY attributes for later use.
tcgetattr(fd, &curr);
endwin();

/*
* Set the shell/non-curses mode TTY attributes to
* match those of program/curses mode (3 attempts).
*/
memcpy(&new_shell_mode, &curr, sizeof curr);
for (c = 0; c < 3; c++) {
tcsetattr(fd, TCSADRAIN, &new_shell_mode);
tcgetattr(fd, &curr);
if (0 == memcmp(&new_shell_mode, &curr, sizeof curr))
break;
}
// If new shell mode could fully be set, get a key press.
if (c != 3)
c = getch();
reset_shell_mode();
delscreen(sp);
fclose(ttyf);
printf("%02X\n", c);
return 0;
}

但是,考虑到我已经退出了curses模式,仍然以所示方式使用getch()实际上是否安全/可移植?

或者我是否需要采取更困难的路径,使用 setupterm() 加载 terminfo DB 并循环遍历 strnames 数组,调用 tigetstr( ) 对于每个,加上手动设置我自己的 termios 标志并自己处理读取按键?

XSI Curses 规范中似乎没有禁止这一点,只要 stdscr 保持有效,这似乎直到程序退出或调用 delwin() 为止,我可以继续使用它,并且由于 stdscr 连接到我的 ttyf 文件(即终端),我可以使用它来获取按键,而无需自己处理所有事情。

最佳答案

您使用 newterm 初始化了curses,并且您调用 endwin 并不重要:curses将如果它执行 refresh 作为调用 getch 的副作用,则恢复全屏模式。

这不仅仅是 ncurses,而是任何curses 实现(除了 20 世纪 80 年代早已过时的 BSD 版本)。 X/Open Curses注释

If the current or specified window is not a pad, and it has been moved or modified since the last refresh operation, then it will be refreshed before another character is read.

在您的示例中,没有任何内容被“移动或修改”。但 getch 检查。 ( endwin /termios 内容可能没有任何好处,因为 newterm 在第一个 refresh 之前不会执行清屏操作) .

关于c - 在curses 模式之外使用getch 的可移植性如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54164942/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com