【问题标题】:Receiving keystrokes接收击键
【发布时间】:2014-11-26 19:23:38
【问题描述】:

有没有办法在 TTY 驱动程序遇到换行符或 EOF 之前读取用户输入,但不使用 /dev/input/event* 我尝试在循环中使用 write(3),但这需要等待 TTY 驱动程序将数据发送到进程的标准输入。另外,如果我理解正确,使用 /dev/input/event* 将捕获 all 击键。我只对在遇到EOF\n 之前阅读stdin 感兴趣。

【问题讨论】:

    标签: c linux


    【解决方案1】:

    您需要将stdin 置于非规范模式,如果stdin 是终端或伪终端,您可以这样做。请参阅man tcgetattrman termios(可能是相同的联机帮助页)。是的,阅读量很大:)

    您很可能拥有库函数cfmakeraw,这是将stdin 置于原始模式的最简单方法。只要您定义 _BSD_SOURCE 功能测试宏,GNU C 库就可以使用它。 cfmakeraw 将执行所有原始模式的常规设置,包括关闭回显,因此您必须自己回显输入到stdout 的字符。您还必须处理解释退格和箭头字符,以及所有其他精巧的熟(逐行或规范)输入。

    此外,请确保将终端重置为正常模式即使您的程序崩溃。 (为此,您需要使用 atexit。)

    对于它的价值,您可能会发现使用 ncurses 库更简单。

    【讨论】:

    • 好的,我会先提到ncurses。否则,rici 所说的。
    【解决方案2】:

    更改终端设置以禁用一次一行输入。请务必在程序退出时恢复终端设置。

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <termios.h>
    #include <unistd.h>
    
    #define CNTL_D 4
    
    static struct termios oldtty, newtty;
    
    void kbcleanup( void )
    {
        tcsetattr( 0, TCSAFLUSH, &oldtty );     /* restore old settings */
    }
    
    int kbsetup( void )
    {
        tcgetattr( 0, &oldtty );
    
        newtty = oldtty;
    
        newtty.c_lflag &= ~ICANON;  /* disable line-at-a-time input */
        newtty.c_lflag &= ~ECHO;    /* disable echo */
    
        if ( tcsetattr( 0, TCSAFLUSH, &newtty ) == 0 ){
            atexit( kbcleanup );    /* restore the terminal settings when the program exits */
            return( 1 );
        } else {
            return( 0 );
        }
    }
    
    int main( void )
    {
        int c;
    
        if ( !kbsetup() )
        {
            fprintf( stderr, "Unable to set terminal mode\n" );
            exit( 1 );
        }
    
        while ( (c = getchar()) != CNTL_D )
        {
            printf( " -- got char 0x%02x" , c );
            if ( isprint(c) )
                printf( " '%c'\n", c );
            else
                printf( "\n" );
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 2012-01-28
      • 2011-08-18
      • 1970-01-01
      • 2020-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多