问题
C++ newbie trying to make a simple text game on a 2D array.
When I use the switch
statement as shown. It will always print the default value, regardless of what else happens.
From other threads and forums I found it probably has something to do with the getch()
and that it returns the char
as well as \n
.
I have tried for an hour now but I can not solve this. The reason I use getch()
is this: C++ change canonical mode in windows (for reference).
Part of my code now:
//Set up game field
generateField();
setPlayerStart();
//printGameInfo(); TO BE MADE
//Start game while loop
int userInput;
do{
//system("cls"); DISABLED FOR TESTING PURPOSES
printField();
userInput = getch();
switch(userInput){
case 72:{ //ARROW UP
cout << "1What" << endl; //ALSO FOR TESTING PURPOSES
break;
}
case 80:{ //ARROW DOWN
cout << "2What" << endl;
break;
}
case 75:{ //ARROW LEFT
cout << "3What" << endl;
break;
}
case 77:{ //ARROW RIGHT
cout << "4What" << endl;
break;
}
case 113:{ //"q"
return false; //Quit game
}
default:{
cout << "Default..." << endl;
}
}
} while(userInput != 5);
回答1:
Um, I assume you've forgotten how to receive extended keys..
It comes with 0xe0
when extended keys, and it comes with 0x00
when function key (F1-F12)
Change it
userInput = getch();
into
userInput = getch();
if (userInput == 0xe0) // for extended keys
{
userInput = getch();
}
else if (userInput == 0x00) // for function keys
{
userInput = getch();
}
回答2:
Since this is Windows, you can use ReadConsoleInput to read key events. I've separated the parts into functions, but I don't really think the return semantics of handleInput
is all that great.
#include <iostream>
#include <stdexcept>
#include <windows.h>
HANDLE getStdinHandle() {
HANDLE hIn;
if ((hIn = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
throw std::runtime_error("Failed to get standard input handle.");
}
return hIn;
}
WORD readVkCode(HANDLE hIn) {
INPUT_RECORD rec;
DWORD numRead;
while (ReadConsoleInput(hIn, &rec, 1, &numRead) && numRead == 1) {
if (rec.EventType == KEY_EVENT && rec.Event.KeyEvent.bKeyDown) {
return rec.Event.KeyEvent.wVirtualKeyCode;
}
}
throw std::runtime_error("Failed to read input.");
}
bool handleInput(WORD vk) {
switch (vk) {
case VK_UP:
std::cout << "up\n";
break;
case VK_DOWN:
std::cout << "down\n";
break;
case VK_LEFT:
std::cout << "left\n";
break;
case VK_RIGHT:
std::cout << "right\n";
break;
case 'Q': //it's Windows; ASCII is safe
return true;
}
return false;
}
int main() {
try {
auto hIn = getStdinHandle();
while (auto vk = readVkCode(hIn)) {
if (handleInput(vk)) {
return 0;
}
}
} catch (const std::exception &ex) {
std::cerr << ex.what();
return 1;
}
}
Other useful links:
- GetStdHandle
- INPUT_RECORD
- KEY_EVENT
- Virtual key codes
来源:https://stackoverflow.com/questions/24274310/why-does-switch-always-run-default-with-break-included