繁体   English   中英

接收按键

[英]Receiving keystrokes

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

您需要将stdin置于非规范模式,如果stdin是终端或伪终端,则可以执行此操作。 请参见man tcgetattrman termios (可能是相同的手册页)。 是的,这是很多阅读书:)

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

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

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

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

#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" );
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM