C检测带有termios的箭头键效果不佳

时间:2013-12-14 13:20:32

标签: c

我有一个问题,当你按箭头键时你检测到3个输入并且while循环被执行了3次,实际上字符串PRINT OF DEBUG的打印发生了三次。 为什么?我想当你按箭头键时循环执行一次。我该怎么做? 代码如下:

#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#define KEYCODE_R 0x43
#define KEYCODE_L 0x44
#define KEYCODE_U 0x41
#define KEYCODE_D 0x42

int main()
{
    int c;
    printf("\nPRESS A ARROW\n");
    while(1)
    {
        c = getch();
        printf("\nPRINT OF DEBUG\n");
        switch(c)
        {
            case KEYCODE_L:      //rilevazione pressione freccia sinistra
                printf("\nLEFT\n");     
            break;
            case KEYCODE_R:
                printf("\nRIGHT\n");         
            break;
            case KEYCODE_U:
                printf("\nFORWARD\n");
            break;
            case KEYCODE_D:
                printf("\nINDIETRO\n"); 
            break;        
        }
    }
    return 0;
}

int getch() 
{
    char c;
    struct termios before,after;
    tcgetattr (STDIN_FILENO, &before);//STDIN_FILENO e' il File Descriptor dello stdin. Salviamo in before la configurazione attuale dello stdin
    memcpy(&after, &before, sizeof(struct termios)); 
    after.c_lflag &=~ (ICANON | ECHO); //modifichiamo la configurazione dello stadin modificando il flag c_lflag con degli or e and bit a bit
    after.c_cc[VMIN] = 1;
    after.c_cc[VTIME] = 0; 
    tcsetattr (STDIN_FILENO, TCSANOW, &after); //qui effettuiamo effettivamente le modifiche

    if (read (STDIN_FILENO, &c, sizeof(char)) == -1) //read e' una system call, leggiamo dallo stdin
    {
        perror("\nErrore in lettura\nIl programma termina");
        tcsetattr (STDIN_FILENO, TCSANOW, &before);
        exit(-1);
    }

    tcsetattr (STDIN_FILENO, TCSANOW, &before); //si ripristina la configurazione dello stdin
    return c;
}

感谢您的关注

1 个答案:

答案 0 :(得分:1)

getch将最终获得三个十六进制代码:0x1B 0x5B和[0x41,0x42,0x43或0x44]。当它获得0x1B(转义字符)时,switch语句不执行任何操作。对于0x5B也一样。

最后一个字符是你正在处理的字符。如果您想查看某些内容,请在switch语句中添加默认值。添加默认值将告诉您正在获取整个转义序列。 (您应该以不同方式处理输入,除非您绝对确定用户只会按箭头键。)