我相信這是一個非常簡單的問題,但我找不到一個簡單的答案。我有一個無限循環,例如while(1)
,for(;;)
,我需要從按鍵上的循環中斷開。什麼是最簡單的方法來做到這一點?C++ cin keypress事件
P.S .:我不能使用getch
,cin.ignore
或cin.get
,因爲它會停止循環。
我相信這是一個非常簡單的問題,但我找不到一個簡單的答案。我有一個無限循環,例如while(1)
,for(;;)
,我需要從按鍵上的循環中斷開。什麼是最簡單的方法來做到這一點?C++ cin keypress事件
P.S .:我不能使用getch
,cin.ignore
或cin.get
,因爲它會停止循環。
那麼,你想要的是異步輸入。所有由cin
提供的方法等待輸入。你將不得不使用系統特定的功能,或使用一個庫來爲你做。
你需要做的是不僅在一個while循環中處理你的邏輯,而且還從你的操作系統的消息管道收聽。如果您想了解更多關於該方面的信息,請發表評論。
編輯:還有一種方法,但我不會推薦它,因爲它可以是不可移植的,我相信。以下代碼編譯並在VS2012RC下運行。
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{
cout << "Enter a character";
getch();
}
哇,我認爲按鍵這麼簡單的事情將在所有平臺上以相同的方式實現。我知道cin只是一些流,但我仍然認爲會有跨平臺的解決方案。我將在一臺服務器上運行它,其中有一些Linux,但我不知道哪個發行版。我還記得,很久以前,我在學校的Pascal中嘗試了一些東西,只是發生了一個「keypressed」事件,所以我簡單地寫了「重複,直到按下按鈕;」所以在C++中(?){}? – 2012-08-16 13:08:49
那麼,我相信,linux上的消息處理相當簡單。您只需運行一個或兩個操作系統調用來輪詢消息,然後在不想執行任何操作時運行默認操作。本質區別在於,使用流,您可以輸入字符「char」,而在使用OS調用獲得Key Up/Down事件時,可以使用修飾鍵作爲「普通鍵」(shift,ctrl等) – 2012-08-16 13:13:53
「帕斯卡」問題,請看'conio.h' /'getch()'函數。它可以根據您使用的編譯器進行不同的命名,但實際上通常會提供。 (它可以是'getch','getchar'或其他) – 2012-08-16 13:14:56
在C++中沒有「鍵盤」。你只有一個不透明的輸入數據流,你的終端popu 偶爾會有自己的鍵盤輸入。這幾乎總是一個緩衝的,可編輯的行式輸入,所以您無法知道何時按下了任何特定的按鍵。
您需要一個特定於平臺的方法來直接與較低級別的終端進行通信。一個這樣的庫,相當廣泛和便攜,是ncurses
(存在兼容的Windows變體)。便攜式圖形應用程序框架(如SDL和Allegro)也提供原始鍵盤處理。
Omg,std中必須有一個簡單的解決方案。例如,在循環的每一次迭代中,從輸入數據流(cin?)獲取數據並檢查,如果它是空的,但我不知道,如何去做... – 2012-08-16 13:13:35
不,流不允許。看看我的回答下面的評論。 – 2012-08-16 13:15:36
@LukasSalich:這樣看待它:如果你的C++應用程序會收到每一個按鍵事件,它將負責*。例如,你的C++程序必須處理行編輯,這又需要對終端API有深入的瞭解,以便你可以例如按下退格鍵刪除一個字符。爲了保證這種負擔的平均C++應用程序/運行時安全,這不是標準的一部分。但是,有很多這樣的庫,比如conio,ncurses等等。這意味着您可以選擇任何圖書館*最適合您的需求。 C/C++的一大優點。 – DevSolar 2012-08-16 13:20:50
此檢查「左箭頭」被按下時或不:
GetKeyState(VK_LEFT)
而且這不會等待任何東西。只是檢查一些標誌。
WINUSER.H中定義的一些其他鍵:
#define VK_NUMPAD0 0x60
#define VK_NUMPAD1 0x61
#define VK_NUMPAD2 0x62
#define VK_NUMPAD3 0x63
#define VK_NUMPAD4 0x64
#define VK_NUMPAD5 0x65
#define VK_NUMPAD6 0x66
#define VK_NUMPAD7 0x67
#define VK_NUMPAD8 0x68
#define VK_NUMPAD9 0x69
#define VK_CLEAR 0x0C
#define VK_RETURN 0x0D
#define VK_SHIFT 0x10
#define VK_CONTROL 0x11
#define VK_MENU 0x12
#define VK_PAUSE 0x13
#define VK_CAPITAL 0x14
#define VK_KANA 0x15
#define VK_HANGEUL 0x15 /* old name - should be here for compatibility */
#define VK_HANGUL 0x15
#define VK_JUNJA 0x17
#define VK_FINAL 0x18
#define VK_HANJA 0x19
#define VK_KANJI 0x19
#define VK_ESCAPE 0x1B
#define VK_CONVERT 0x1C
#define VK_NONCONVERT 0x1D
#define VK_ACCEPT 0x1E
#define VK_MODECHANGE 0x1F
#define VK_SPACE 0x20
#define VK_PRIOR 0x21
#define VK_NEXT 0x22
#define VK_END 0x23
#define VK_HOME 0x24
#define VK_LEFT 0x25
#define VK_UP 0x26
#define VK_RIGHT 0x27
#define VK_DOWN 0x28
#define VK_SELECT 0x29
#define VK_PRINT 0x2A
#define VK_EXECUTE 0x2B
#define VK_SNAPSHOT 0x2C
#define VK_INSERT 0x2D
#define VK_DELETE 0x2E
#define VK_HELP 0x2F
WINUSER.H必須包含在WINDOWS.H
這僅適用於Windows。它不是跨平臺的(它不是寫在問題中的,而是閱讀評論,你會明白,問題在於某些標準。 – 2012-08-16 13:22:09
對不起,我在編寫答案時沒有閱讀評論^^ – 2012-08-16 13:22:50
下面是使用kbhit()
並具有無限循環Windows控制檯代碼。 但是,如果鍵盤被擊中,它會打破循環並退出。 如果你有<conio.h>
,試試這個:
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
while (1)
{
if (kbhit()) break;
}
return 0;
}
所以我可以在我的循環結束時使用:「if(kbhit())break;」? – 2012-08-16 13:46:51
while while循環中,添加if(kbhit())break; – 2012-08-16 13:51:58
我已經嘗試過,它不工作 – 2012-08-16 14:00:09
在什麼平臺上??? – perilbrain 2012-08-16 13:04:44
如果你告訴我們更多的背景,我敢肯定,我們可以想出一些東西。否則,你需要使用一些操作系統特定的東西。 – 2012-08-16 13:06:34
服務器上的一些Linux。我不知道,哪個發行版。 std中沒有跨平臺的解決方案嗎? – 2012-08-16 13:15:30