problems with getch() input

This topic is 4048 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello, Im having a problem having getch() get the correct input from the arrow keys...maybe i should rephrase that. It gets the arrow key input but when i press a different arrow key it continues from the last arrow key pressed before proceeding with the new input. Any help would be appreciated. Here's my code: #include <iostream> #include <conio.h> #include <cstdlib> #include <windows.h> //#include "useful.h" //#include <curses.h> using namespace std; int main (void) { int d = 0, x=20,y=20; gotoXY(x,y); do{ cout<<'h'; do { d = '\0'; d = (char)getch(); //if(d == 0) d = getch(); }while(d!=72 && d!=80 && d!=75 && d!=77 && d!=1); cout<<'\b'<<' '<<'\b'; switch(d) { case 80: // case up arrow gotoXY(x,y++); break; case 72: // case down arrow gotoXY(x,y--); break; case 75: // case left arrow gotoXY(x--,y); break; case 77: // case right arrow gotoXY(x++,y); break; default: break; } }while (d != 1); getch(); }  //useful.h: #include <iostream.h> #include <windows.h> void gotoXY(int x, int y) { HANDLE screen_buffer_handle = GetStdHandle(STD_OUTPUT_HANDLE); COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(screen_buffer_handle, coord); }

Share on other sites
//if(d == 0) d = getch();

Why don't you use this line? I think uncommenting it should solve the problem.

Also, you might want to use the kbhit() function (returns true if a key was pressed). It can simplify your code and make it not stall (i.e., you only call getch() if you know a key was pressed).

Share on other sites
Directly from MSDN :
When reading a function key or an arrow key, each function must be called twice; the first call returns 0 or 0xE0, and the second call returns the actual key code.

This is for _getch()

Share on other sites
The loop should discard any 0 or 0xe0 character and only pick up the other values, Black Knight. Although, as written, it will also interpret the text inputs H, P, K and M as arrow keys :)

Anyway, to the OP: there isn't a need to make a windows program to interact with the DOS console. That means you don't need windows.h or a wrapper for a gotoXY() function, because conio.h already provides a gotoxy(). (Also, whereever you got that sample code from, it's ancient: note the inclusion of the deprecated iostream.h, which isn't even used anyway.)

I have the following test program, which works when compiled under plain old g++ at the command line:

#include <conio.h>#include <algorithm>int main() {	const int MAX_X = 80;	const int MAX_Y = 25;	int x = MAX_X / 2;	int y = MAX_Y / 2;	clrscr();	gotoxy(x, y);	while (getch() == 0) {		switch (getch()) {			case 'H': y = std::max(y - 1, 1); break;			case 'K': x = std::max(x - 1, 1); break;			case 'P': y = std::min(y + 1, MAX_Y); break;			case 'M': x = std::min(x + 1, MAX_X); break;		}		gotoxy(x, y);	}}

This only moves the cursor around (without putting a symbol at that location) until any non-arrow-key is pressed. Note that parameters to gotoxy() are 1-based; using 0 for either x or y will have weird results. I don't know under what conditions a 0xE0 (224) is sent for the first byte instead of a 0; you should probably check for both. I did manage to reproduce the problem you're reporting by putting the gotoxy() call *between* the two getch()es, so that may be a hint. ;) (Think carefully about the logic - consider getch() like a queue, where each key press puts either one or two characters in, and each call pulls one out if there are any, and otherwise waits for input). Anyway, this setup is clean and should be easily adaptable to your purpose.

Also, what are you hoping to detect by checking for a getch() result of 1? :/

Share on other sites
thank you everyone! and regarding the conio.h thing, im using dev and gotoxy() is not a part of that compiler (its really frustrating as we usually use borland at school and that conio.h does have it). also i just haven't coded the exit for this program, i just didnt know what i was going to do...but as this is only a test program i figured i didnt really need an exit ( :[ im not that much of a noob... :] ). but anyways i do appreciate the help, thanks.

[Edited by - Mikaljr on July 17, 2007 2:33:22 PM]

Share on other sites
Quote:
 Original post by Zahlman#include #include int main() { const int MAX_X = 80; const int MAX_Y = 25; int x = MAX_X / 2; int y = MAX_Y / 2; clrscr(); gotoxy(x, y); while (getch() == 0) { switch (getch()) { case 'H': y = std::max(y - 1, 1); break; case 'K': x = std::max(x - 1, 1); break; case 'P': y = std::min(y + 1, MAX_Y); break; case 'M': x = std::min(x + 1, MAX_X); break; } gotoxy(x, y); }}

for some reason this did not work...even after i tried stalling the program it just took in a keyboard hit and exited, whether it was an arrow key or anything else. anything i am doing wrong?

Share on other sites
My recent testing (yesterday to be exact) nder VS2005 is _getch() (or getch()) would return 0xE0 for arrow keys and 0x00 for function keys.

If I remember correctly, my Turbo C++ DOS days was getch() would return 0 for all 'extended' keys.

p/s: Learn new things everyday.

Share on other sites
Quote:
 Original post by DerekSawMy recent testing (yesterday to be exact) nder VS2005 is _getch() (or getch()) would return 0xE0 for arrow keys and 0x00 for function keys.If I remember correctly, my Turbo C++ DOS days was getch() would return 0 for all 'extended' keys.p/s: Learn new things everyday.

Yeah, you'll need to check for both. I have no idea what determines which "marker" byte is sent. :)

Share on other sites
If you use Clanlib or just about any game library, they have methods for polling the keyboard that will allow the user to press multiple keys simultanously. For games, these APIs are pretty necessary.

1. 1
2. 2
3. 3
4. 4
frob
15
5. 5

• 9
• 12
• 20
• 12
• 13
• Forum Statistics

• Total Topics
632147
• Total Posts
3004444

×