這是前兩天,和網友討論的東西。主要命題就是:「要怎麼用 C++ 寫一個 console 的程式,可以取得單一按鍵的輸入?」也就是類似「按任一鍵繼續」的功能了~
Heresy 本來以為很簡單,後來才發現非常地麻煩… 首先,一般習慣在用的 scanf() 或是 cin,都必須要按下 Enter 後,才會開始處理;找了好一段時間的資料,也試了好久,才大概確定,他們應該都沒有辦法符合這個要求。
而在 Windows 上用 Visual C++ 的話,只要先 include conio.h 後,就可以直接使用 getch() 這個函式了~完整程式,也就只要下面這樣就夠了
#include <stdio.h> #include <conio.h> int main(void) { printf("Press any key to continue..."); int a = getch(); printf( "%dn", a ); return 0; }
但是到了 Linux 一般用的 g++ 呢…第一個問題就是沒有 conio.h 這個檔案了…
不過,在 Google 找一下,就可以發現,可以發現在 curses.h 這個標頭檔裡,也有定義 getch() 這個函式(參考:The Single UNIX ® Specification,編譯時需加入 -lcurses 的參數)!
可是,問題還是沒解決。因為 curses.h 裡的 getch() 不能像 Windows 版的一樣,直接用… = =
Heresy 後來才知道,原來他要使用 curses.h 裡的功能,必須要先透過 initscr() 這個函式,來初始化一個 screen(window),才能針對這個 window 做操作。而參考的寫法,大概如下:
#include <curses.h> int main(void) { WINDOW *w = initscr(); // cbreak(); // nodelay(w,false); int c = getch(); endwin(); printw("%dn",c); return 0; }
其中,cbreak() 和 nodelay() 這兩個函式是被 mrak 掉了。因為像在找到《c++ g++ wait for key press???》這篇的範例,就是有加上這個 cbreak() 函式;而有加上 nodelay() 的版本,則是 Heresy 同事給的範例。但是 Heresy 自己在測試時,好像沒加也都沒差就是了…
而另外,Heresy 有位網友也提供了一種透過 POSIX 來實作 getch() 的方法(請見《implement getch() on POSIX.1 OS》);其程式如下:
#include <stdio.h> // POSIX headers #include <termios.h> // for tcxxxattr, ECHO, etc .. #include <unistd.h> // for STDIN_FILENO int getch(void); int main(void) { printf("Press any key to continue..."); getch(); return 0; } int getch (void) { int ch; struct termios oldt, newt; tcgetattr(STDIN_FILENO, &oldt); memcpy(&newt, &oldt, sizeof(newt)); newt.c_lflag &= ~( ECHO | ICANON | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL); tcsetattr(STDIN_FILENO, TCSANOW, &newt); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); return ch; }
整個弄完後的感想,只有一個:要用 C++ 寫一個跨平台的程式,可以抓到單一按鍵的輸入還真麻煩啊…
[…] 在下面这个网页上有详细的讨论: There’s some detailed discussion on this page below (in Traditional Chinese): 在 Linux 上实作 C++ 在 VC++ 的 getch() […]
讚讚
感謝 正好用到~~ :)
讚讚
to 御倫
有註明出處就 ok 囉~ :)
讚讚
你好,我剛好也在找這個問題,請問你的文章可以讓我貼在我的網誌上面嗎?我會做一個連結註明出處,不知道是否可以,謝謝!
讚讚
又打錯字了 orz
不過 Linux 上用 g++ 寫程式還好啦~
標準語法都還是通用的。除非要寫 UI,不然差異不會太大。
讚讚
其實我也正在進軍LINUX上的C++程式耶,不過目前進度很慢,沒有領隊..XD開路吧Heresy!可以取得單一安鍵的輸入?…"安"鍵
讚讚