Reputation: 11914
So I'm thinking about how to catch keyboard activities in C. As we all know, we can type something and press Enter to stream in whatever we want to send to the computer. But the first question is, how to input some untypeable characters like up arrow, down arrow (especially these two guys because I'm using Linux but want to use them for something other than their default meanings), shift, ctrl or whatever. Second, how to make the program proceed right after we press any key, so we don't need to enter and enter all the time. (It's like "Press any key to continue" in Windows).
Upvotes: 1
Views: 3604
Reputation: 121799
The "universal" method is getchar (). Getchar()" uses "buffered input": you don't actually get any output until the user presses "Enter". And it isn't really applicable unless you're using a command prompt (or equivalent).
The old DOS way was getch() and getche(), from "conio.h". That method doesn't exist in modern C/C++ libraries targeting modern operating systems.
SUGGESTION:
If you want to create a text-mode UI (especially on Linux), take a look at ncurses:
If you want to program a game (on Windows or Linux), take a look at SDL:
=== ADDENDUM ===
I still recommend a library ... but here's a function that illustrates "raw keyboard input" (aka "uncooked", or "non-canonical" input) under Linux:
http://cboard.cprogramming.com/c-programming/63166-kbhit-linux.html
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
void changemode(int);
int kbhit(void);
int
main(int argc, char *argv[])
{
int ch;
changemode(1);
while ( !kbhit() )
{
putchar('.');
}
ch = getchar();
printf("\nGot %c\n", ch);
changemode(0);
return 0;
}
void
changemode(int dir)
{
static struct termios oldt, newt;
if ( dir == 1 )
{
tcgetattr( STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
}
else
tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}
int
kbhit (void)
{
struct timeval tv;
fd_set rdfs;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rdfs);
FD_SET (STDIN_FILENO, &rdfs);
select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &rdfs);
}
Upvotes: 0
Reputation: 5491
In the DOS days, there was a kbhit()
function. If you need that functionality you can look at this thread: kbhit() for linux.
I vaguely recall trying the user Thantos' function and it working rather well.
I do recommend you read up on what the tcgetattr()
and tcsetattr()
functions first.
Upvotes: 1
Reputation: 796
stty
command.system ("/bin/stty raw");
before you using getchar()
man stty
. termios.h
herenewt.c_lflag &= ~(ICANON | ECHO);
man termios.h
Upvotes: 2
Reputation: 667
If you are using Linux the best bet for keyboard input is the GNU readline library.
This provides all the functionality out of the box including emacs and vi editing modes if you want them.
/* A static variable for holding the line. */
static char *line_read = (char *)NULL;
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
char *
rl_gets ()
{
/* If the buffer has already been allocated, return the memory to the free pool. */
if (line_read)
{
free (line_read);
line_read = (char *)NULL;
}
/* Get a line from the user. */
line_read = readline ("");
/* If the line has any text in it, save it on the history. */
if (line_read && *line_read)
add_history (line_read);
return (line_read);
}
MIT has some great tutorials.
Upvotes: 0