因為寫了一支基於 sensor 的 real-time process ,會不斷地讀取感測器的輸出並計算結果,基本上是一個 Firmware 的運作模式,但先在 Linux Ubuntu OS 測試,需要透過鍵盤輸入一個訊號來終止程序中的 while loop ,或是做為 switch 開關程序中的功能,因此需要實做 getche 函數。
getch 是一個函數,能夠取得鍵盤輸入的訊號,甚至進一步判別按下的按鍵。在 Windows 環境下 include conio.h 頭文件,就能使用 getch & getche 函數,但因為這些不是 C 的標準函式庫,在 Mac 及 Linux OS 不支援 conio.h 頭文件,只能自己實做。 getch 、 getche 與 getchar 的比較如下表:
螢幕回應 | 使用 buffer (需按下 Enter 鍵) | |
getch | No | No |
getche | Yes | No |
getchar | Yes | Yes |
我參考的寫法基於 tcgetattr() 和 tcsetattr() 兩個終端函數,參考來源:
https://zhuanlan.zhihu.com/p/525999190
#include <termios.h>
char getche(void)
{
struct termios oldt, newt;
char a;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
a = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return a;
}
int main() {
char a;
a = getche();
printf("You just type '%c' out\n", a);
return 0;
}
但是按照預設的終端設定,程式會阻塞在 getche() 函數,我希望程序持續運行,直到我按下鍵盤才做反應,因此還需要對 stdin 做以下設定:
#include <unistd.h>
#include <fcntl.h>
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
參考來源:
https://juejin.cn/s/linux%20c%20getchar%20non%20blocking
最後,以我實做的 GNSS / IMU 組合慣性導航算法為例,程序會持續 while loop 新的 GNSS 與 IMU 資料進行融合運算,當我按下 Q 鍵時,程序會跳出迴圈,並顯示最終的定位結果,或是按下 G 鍵時,disable GNSS 相關的函數。
在〈getche 鍵盤互動 -【C 語言學習筆記】〉中有 1 則留言
留言功能已關閉。