類getch()功能的實現
I
只要在Windows下用過C/C++就會很熟悉conio.h
庫中的一個函數getch()
,它可以繞過終端輸入緩沖區直接從鍵盤讀取一個字符,並且不在界面上顯示。
但如果想直接在Linux環境下用是不行的,因為沒有conio.h
庫的支持。
博主翻了網上的一些資料,在這里給出一個比較簡明的實現,使用起來與Windows下沒什么差異。
#include<cstdio>
#include<cstdlib>
inline char getch(){
static char ch;
system("stty -icanon -echo");
scanf("%c",&ch);
system("stty icanon echo");
return ch;
}
II
不知道大家有沒有遇到這樣的問題:平時所見的輸入語句都需要等待我們輸入完才會執行完成,什么都不做的話就會一直阻塞在那里。但我們有時想讓程序在嘗試接收讀入失敗的時候能夠繼續執行下去。這樣要怎么實現呢?
我們需要一個函數fcntl
,包含在fcntl.h
中。使用它可以取消輸入阻塞。關於它的更詳細的內容可以百度。
我們還需要一個函數read
,包含在unistd.h
中,是一個底層的輸入函數。
定義一個CustomGetch
類,包含構造函數、析構函數和運算符()
重載,再定義一個該類變量getch
,用起來就像函數一樣。
#include<cstdlib>
#include<fcntl.h>
#include<unistd.h>
class CustomGetch{
public:
CustomGetch(){
fcntl(0,F_SETFL,O_NONBLOCK);
system("stty -icanon -echo");
}
~CustomGetch(){
fcntl(0,F_SETFL,0);
system("stty icanon echo");
}
inline char operator()(){
static char ch;
return ~read(0,&ch,1)?ch:EOF;
}
}getch;
這樣寫有一個局限性:在這個變量的生存周期內,不能和其它的輸入方式兼容。因此有兩種處理方案:
- 在需要
getch()
而不需要其它輸入方式的語句塊內定義臨時變量。 - 直接像I中的那個
getch()
一樣寫成函數。但考慮到實際應用中要頻繁調用這個函數對輸入流進行檢查,而system
操作相當耗時,所以不推薦這樣做。
清屏
因為system("clear")
是個假的清屏,所以我們需要更好的實現。
printf("\033c");
對,沒了,就一行。
程序示例
#include<cstdio>
#include<cstdlib>
int main(){
for(int i=0;;++i){
printf("\033c");
for(int j=0;j<4;++j)puts(1&i?"abcdefg":"abcbefg");
system("sleep 1");
}
return 0;
}
更改輸出起始位置、輸出字體顏色
Linux終端有專門的轉義字符。看這個博客