getche 鍵盤互動 -【C 語言學習筆記】

因為寫了一支基於 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 鍵)
getchNoNo
getcheYesNo
getcharYesYes

我參考的寫法基於 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 相關的函數。

https://mapostech.com/gnss-nmea/
getche
Photo by Jeremy Bishop on Pexels.com
上一篇:
下一篇:

在〈getche 鍵盤互動 -【C 語言學習筆記】〉中有 1 則留言

留言功能已關閉。