2012-02-24 112 views
0

我現在正在使用下面的函數。但我需要改進的是它會從鍵盤讀取輸入(在終端上),即使它沒有被按下。我需要知道它何時未被按下(空閒),以便switch case塊將落入default部分。此時,read()函數會等待用戶輸入。任何人都可以給出一個建議,只是基於修改以下代碼? 注意:我是一名Java程序員,仍在學習C/C++,因此可能很難讓我有點頭腦。謝謝你們..非阻塞鍵盤讀取 - C/C++

編輯:我發現這個鏈接,似乎有什麼我想找的東西在fcntl(STDIN_FILENO,F_SETFL,flags | O_NONBLOCK);行。但是因爲我幾乎不知道C中的任何內容,所以我完全不知道它在說什麼。
http://www.codeguru.com/forum/showthread.php?t=367082

int kfd = 0; 
struct termios cooked, raw; 
char c; 
bool dirty = false; 

//get the console in raw mode 
tcgetattr(kfd, &cooked); 
memcpy(&raw, &cooked, sizeof(struct termios)); 
raw.c_lflag &=~ (ICANON | ECHO); 
// Setting a new line, then end of file 
raw.c_cc[VEOL] = 1; 
raw.c_cc[VEOF] = 2; 
tcsetattr(kfd, TCSANOW, &raw); 

puts("Reading from keyboard"); 
puts("====================="); 
puts("Use arrow keys to navigate"); 

while(true){ 
//get the next event from the keyboard 
if(read(kfd, &c, 1) < 0) 
{ 
    perror("read():"); 
    exit(-1); 
} 

linear_ = angular_ = 0; 
ROS_DEBUG("value: 0x%02X\n", c); 

switch(c) 
{ 
    case KEYCODE_L: 
    ROS_DEBUG("LEFT"); 
    angular_ = -1.0; 
    dirty = true; 
    break; 
    case KEYCODE_R: 
    ROS_DEBUG("RIGHT"); 
    angular_ = 1.0; 
    dirty = true; 
    break; 
    case KEYCODE_U: 
    ROS_DEBUG("UP"); 
    linear_ = 1.0; 
    dirty = true; 
    break; 
    case KEYCODE_D: 
    ROS_DEBUG("DOWN"); 
    linear_ = -1.0; 
    dirty = true; 
    break; 
    default: 
    ROS_DEBUG("RELEASE"); 
    linear_ = 0; 
    angular_ = 0; 
    dirty = true; 
    break; 
} 
+1

而不是直接使用termios的,我建議使用類似[ncurses的(HTTP://en.wikipedia .ORG /維基/ Ncurses的)。 [Here](http://hughm.cs.ukzn.ac.za/~murrellh/os/notes/ncurses.html)是一個教程,展示瞭如何以非阻塞的方式獲取密鑰。 – 2012-02-24 10:37:48

+0

僅僅修改上面的代碼是沒有辦法的嗎?我只是想從終端讀取鍵盤輸入(忘記提及)。當然,我最後的手段是學習ncurses,但我已經很難學習C/C++。 – 2012-02-24 10:47:06

+0

@JoachimPileborg我編輯了我的問題(我認爲是)相關的鏈接。你認爲你知道它在說什麼嗎? – 2012-02-24 10:53:40

回答

1

的OP似乎已經回答了自己的問題:

我想我解決我的問題。請任何人都確認並告訴我是否這是正確的做法,或者它是完成這種做法的完整方式(我錯過了其他任何添加步驟,例如重新設置它,即使這樣做有意義)。

所以我發現在進入while循環前添加以下3行:

flags = fcntl(0, F_GETFL, 0); /* get current file status flags */ 
flags |= O_NONBLOCK;   /* turn off blocking flag */ 
fcntl(0, F_SETFL, flags);   /* set up non-blocking read */