Jump to content
  • Advertisement
Sign in to follow this  
Mikaljr

problems with getch() input

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement

//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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Zahlman


#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);
}
}



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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by DerekSaw
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.


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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!