Click to See Complete Forum and Search --> : How to wait for user to enter key but not require enter?
Red Squirrel
July 14th, 2008, 05:54 PM
I'm trying to make a function that will wait for user to press on any key then continue execution of program without requiring to use enter.
Also looking for it to be platform inderpendant (at worse I can use ifdef if theres two similar functions).
Looking for something like getch() basically, but more ansi standard.
I tried cin.get(), getchar() but both require user to hit enter.
Must work in linux and windows. And please don't say system("pause") I'm looking for an actual function! Writing my own header/library so I can stop having to reinvent the wheel every time I code C++. Planing on writing a large project once this set of libs is done.
sszd
July 14th, 2008, 06:29 PM
Don't know about Windows, but in Unix look into curses.h. You can do a man on curses...
$ man curses
I assume linux has this, or something similar.
Red Squirrel
July 14th, 2008, 07:25 PM
Curses seems to be Linux only, is there something thats both for windows and linux?
Paul McKenzie
July 14th, 2008, 07:36 PM
Curses seems to be Linux only, is there something thats both for windows and linux?Not portably, unless there is a curses port for Windows.
Internally, waiting for a keypress is OS dependent. For Linux/Unix, I remember having to place the terminal in "raw" mode, and call ioctl() with some parameters, and I guess curses does the same thing.
None of this is required for Windows, as the OS handles the keypress events and routing them to the app.
Regards,
Paul McKenzie
Red Squirrel
July 14th, 2008, 07:50 PM
What about doing this in "raw mode". from what I'm reading curses requires to include a library too. As this will be a base set of function/classes to use throughout all my apps I want to avoid libraries as much as possible to avoid complexity. Is there ways I can just access the terminal directly myself? I was thinking of embeding assembly and using interrupts but can't seem to get that to work either. I tried _asm{ } __asm{ } and so on, no luck.
Red Squirrel
July 14th, 2008, 08:58 PM
There think I got it. Can't believe this is so complicated for something silly like this, though. I'm more of a core back end guy, I hate designing UIs, thats why I code game servers, not game clients. :P
Anyway this is what I got:
unsigned int GetChar()
{
#ifdef WIN32
return getch();
#else
int ch;
struct termios oldt, newt;
tcgetattr ( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
return ch;
#endif
}
The windows version uses conio.h which I've always used before I got into Linux and the Linux version uses termios.h.
Paul McKenzie
July 15th, 2008, 03:47 AM
Is there ways I can just access the terminal directly myself?Yes, by using the terminfo/termio information. It's been over a decade, but this is how you do this without any libraries, just the terminfo/termio information. You don't need curses, but curses already has done the terminfo functionality for you.
I wrote a windowing library around 15 years ago that was cross-platform (DOS / Unix / Linux). The Linux keyboard stuff was one of the things I had to work on.
I was thinking of embeding assembly and using interrupts but can't seem to get that to work either. I tried _asm{ } __asm{ } and so on, no luck.There is no need for assembly if you're talking about the Linux stuff. The trick is to make sure the terminal is in raw mode and the echo is turned off (and I believe buffering is turned off). Here is code I wrote a *long* time ago -- use at your own risk:
#include <term.h>
#include <terminfo.h>
#include <fcntl.h>
struct termio tbufsave;
void setraw()
{
struct termio tbuf;
ioctl(0,TCGETA,&tbuf);
tbufsave = tbuf;
tbuf.c_iflag &= ~(INLCR | ICRNL | IUCLC | ISTRIP | IXON | BRKINT);
tbuf.c_oflag &= ~OPOST;
tbuf.c_lflag &= ~(ICANON | ISIG | ECHO);
tbuf.c_cc[4] = 1;
tbuf.c_cc[5] = 1;
ioctl(0,TCSETAF,&tbuf);
}
The tbufsave is necessary to make sure you set the terminal back to "cooked" when you're done. If not, I'm not sure what state the keyboard will be in once your program terminates.
Regards,
Paul McKenzie
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.