0

我正在研究我认为应该是一个简单的程序,我用谷歌搜索过,我能找到的只是 C#、C++ 的东西。

我想要完成的是启动我编写的程序C并让它监听某些击键。我编写了一个可以移动伺服的函数,因此我想集成向上和向下箭头键来执行将伺服移动到一个方向或另一个方向的功能。这可能C吗?

4

1 回答 1

3

你是在linux还是windows上工作?基于此,可以使用替代方案。如果您在 Windows 上工作,您应该熟悉一个函数:kbhit()?虽然它现在已被弃用,但它的工作知识可能很有用:) 假设您正在使用 linux,您是否尝试过 NCurses?

取自[这里]:(http://www.linuxmisc.com/9-unix-programmer/d5b30f8d1faf8d82.htm

问题有三个方面:

  1. 您必须检查数据是否在没有阻塞的情况下可用。一个简单的“读取”或 fgets 或任何会阻止您的进程,直到数据可用 - 您不希望这样。
  2. 您必须绕过任何缓冲,否则您将不得不同时检查缓冲区和设备。
  3. 您需要强制终端驱动程序在可用时为您提供数据,而不是将整个数据累积成一行。

从同一页面:

也就是说,我提出了以下笨拙、仓促编写、未注释的代码,这些代码可能具有指导意义,也可能没有(部分由我编辑,缺少括号且未缩进)

#include <stdio.h> 
#include <termios.h> 
#include <unistd.h> 
#include <sys/time.h> 
#include <sys/types.h> 

static struct termios orig_term; 
void u_cleanup(void) 
{ 
    tcsetattr(0, TCSANOW, &orig_term); 
}
int u_kbhit(void) 
{ 
    struct termios t; 
    int ret; 
    fd_set rfd; 
    struct timeval to; 
    static int first_hit=0; 
    if(first_hit==0) 
    { 
        if(tcgetattr(0, &t)!=0) exit(0); 
        orig_term=t; 
        cfmakeraw(&t); 
        if(tcsetattr(0, TCSANOW, &t)!=0) exit(0); 
        atexit(u_cleanup); 
        first_hit=1; 
    } 

    FD_ZERO(&rfd); 
    FD_SET(0, &rfd); 
    to.tv_sec=0; 
    to.tv_usec=0; 
    if(select(1, &rfd, NULL, NULL, &to)==1) return 1; 
    return 0; 
}
int u_getchar(void) 
{ 
    int ret; 
    fd_set rfc; 
    unsigned char buf; 
    if(read(0, &buf, 1)!=1) ret=0; 
    else ret=buf; 
    return ret; 
}

int main(void) 
{ 
    while(1) 
    { 
        if(u_kbhit()) 
        { 
            int key=u_getchar(); 
            printf("hit: %d\r\n", key); 
            if(key==3) 
            { 
                printf("you hit control-c\r\n"); 
                exit(0);                         
            }         
        } 
        usleep(100); 
    }
    return 0; // inaccessible code, to prevent compiler warning
 }
于 2013-04-09T03:44:40.643 回答