天天看點

如何在類 Unix 環境下無需等待回車即可擷取來自鍵盤的輸入?

在類 Unix 作業系統中,C++ 程式使用 stdio 或 iostream 程式庫接收鍵盤輸入時,需等待Enter鍵按下後才能接收到輸入内容。如何能在無需等待回車即可擷取來自鍵盤的輸入?

通過 termios 程式庫中與終端關聯的 termios 結構和 tcgetattr、tcsetattr 函數,改變終端編輯模式為非規範輸入且不回顯,即可實作“無需等待回車即可擷取來自鍵盤的輸入”的功能。

以下代碼片段展示了此實作方案,(how_to_get_input_without_enter.cpp)

首先需要包含 termios.h 程式庫(#1),該檔案定義了與終端關聯的 termios 結構和 tcgetattr、tcsetattr 函數。使用 tcgetattr 函數擷取目前終端的屬性,并儲存在 termios 結構的變量中(#2)。為了能将終端屬性恢複成原有值,先用原有終端屬性複制出一份臨時屬性(#3)。改變終端編輯模式的關鍵,在于 termios.c_lflag 字段。将臨時屬性的 c_lflag 字段改變為非規範輸入且不回顯(#4),并設定終端屬性為新值。應用結束後,将終端屬性恢複成原有值(#5)。

筆者分别在 macOS Mojave(版本 10.14.6)和 Raspbian Stretch(版本 9.4)兩個作業系統的原生終端内,用 87 鍵鍵盤輸入 ASCII 字元集進行了驗證。

編譯代碼成功後運作可執行檔案。對于十進制 ASCII 碼為 32 ~ 127 的可列印字元可直接按鍵輸入,而對于 ASCII 碼為 0 ~ 31 的控制字元按如下組合鍵輸入,

十進制

字元

macOS Mojave 組合鍵

Raspbian Stretch 組合鍵

^@

Ctrl-@

1

^A

Ctrl-A

2

^B

Ctrl-B

3

^C

Ctrl-V Ctrl-C

(未驗證)

4

^D

Ctrl-D

5

^E

Ctrl-E

6

^F

Ctrl-F

7

^G

Ctrl-G

8

^H

Ctrl-H

9

Tab, ^I

Tab, Ctrl-I

10

^J

Ctrl-J

11

^K

Ctrl-K

12

^L

Ctrl-L

13

^M

Ctrl-V Ctrl-M

14

^N

Ctrl-N

15

^O

Ctrl-V Ctrl-O

Ctrl-O

16

^P

Ctrl-P

17

^Q

Ctrl-V Ctrl-Q

18

^R

Ctrl-R

19

^S

Ctrl-V Ctrl-S

20

^T

Ctrl-T

21

^U

Ctrl-U

22

^V

Ctrl-V Ctrl-V

Ctrl-V

23

^W

Ctrl-W

24

^X

Ctrl-X

25

^Y

Ctrl-V Ctrl-Y

Ctrl-Y

26

^Z

Ctrl-V Ctrl-Z

27

ESC, ^[

Ctrl-[

ESC, Ctrl-[

28

^\

Ctrl-V Ctrl-\

29

^]

Ctrl-]

30

^^

Ctrl-^

31

^-

Ctrl--

在 Raspbian Stretch 上的測試中存在”(未驗證)“的 ASCII 碼,是因為該示例代碼無法通過鍵盤輸入對應的控制符。

以下是運作過程中的部分輸出,

完整示例代碼請參考 [github] cnblogs/15691156 。

寫作過程中,筆者參考了 Linux下C++/C終端擷取鍵盤事件/termios結構詳細解釋 和 LINUX 使用tcgetattr與tcsetattr函數控制終端。緻 Liuqz2009 和 凡人隻做一事 兩位作者。

受限于作者的水準,讀者如發現有任何錯誤或有疑問之處,請追加評論或發郵件聯系 [email protected]。作者将在收到意見後的第一時間裡予以回複。 本文來自部落格園,作者:green-cnblogs,轉載請注明原文連結:https://www.cnblogs.com/green-cnblogs/p/15691156.html 謝謝!

繼續閱讀