首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用getch外部诅咒模式有多便携?

问使用getch外部诅咒模式有多便携?
EN

Stack Overflow用户
提问于 2019-01-12 23:52:08
回答 1查看 256关注 0票数 3

我正在编写一个终端程序来识别单个按键,包括键盘键,但如果可能的话,我不希望在诅咒/程序模式下这样做。我认为我可能只是利用诅咒和tcgetattr()和tcsetattr()来完成我想要的外部诅咒模式,而不是使用诅咒I/O函数为我完成键盘键的转换,而不是使用still和某种映射或树结构来实现快速键盘键匹配。令我非常惊讶的是,这是可行的(Linux,ncurses 6.1.20180127):

代码语言:javascript
复制
/**
 * 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;
}

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

或者,我是否需要采取更困难的路径,使用setupterm()加载strnames数组并遍历strnames数组,为每个数组调用tigetstr(),再手动设置自己的termios标志,并自行读取按键呢?

XSI规范中没有任何东西禁止这一点,只要stdscr仍然有效,这似乎在程序退出或调用delwin()之前都是有效的,我可以继续使用它,而且由于stdscr连接到作为终端的ttyf文件,所以我可以使用它获得按键,而无需自己处理一切。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-13 01:07:47

您使用newterm,初始化了诅咒,如果使用refresh作为调用getch.的副作用,那么您调用的将恢复全屏模式。

这不仅是ncurses,还包括任何诅咒实现(除了1980年代长期过时的BSD版本)。X/公开诅咒注释

如果当前或指定的窗口不是衬垫,并且自上次刷新操作以来已被移动或修改,则将在读取其他字符之前刷新该窗口。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54164942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档