Alan wrote:
I am using Standard C compiled with GCC under Linux Fedora Core 4
When I run this program and enter a character at the prompt, I have to
press
the ENTER key as well. This gives me 2 input characters - 'a' and
'\n' (Hex 61 and 0a)
It seems as though the getchar() function needs ENTER to terminate reading
stdin.
I am trying to get the program to respond when I press one key only (ie
without needing to press ENTER as well).
Program
~~~~~~~
#include <stdio.h>
#include <stdlib.h>
int main()
{
char x; //Input character
while (1)
{
printf(">"); //Print prompt '>'
x = getchar(); //Get input character
printf("%d %02x \n", x, x);//Print character in decimal &
Hex
if (x == 'q') //Exit if the character is 'q'
exit(0);
}
}
Output
~~~~~a < input character
97 6110 0a
b < input character
98 6210 0a
c < input character
99 6310 0a
d < input character
100 6410 0a
q < input character
113 71
I have tried using scanf() but got the same results.
Any ideas as to how I can input ONE character only? TIA :)
Alan
Search the net for kbhit.c there's a version of it out there for linux, i
use it a lot and it solves these kinds of problems. Just add the kbhit.c
file to your Makefile and put #include "kbhit.h" in your program.
Call init_keyboard() at top of program and close_keyboard() on or before
exit. These two steps are really important, dont forget them.
Warning: failure to call close_keyboard() before your program exits will
leave your keybaord in a really weird state.
Ah hell, its short enough - Here...
Eric
/* The following code is kbhit.c */
#include "kbhit.h"
#include <termios.h>
#include <unistd.h> // for read()
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard()
{
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard()
{
tcsetattr(0, TCSANOW, &initial_settings);
}
int kbhit()
{
unsigned char ch;
int nread;
if (peek_character != -1) return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1)
{
peek_character = ch;
return 1;
}
return 0;
}
int readch()
{
char ch;
if(peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}
/*
kbhit.c EOF
*/
/* The following code is kbhit.h */
#ifndef __KBHIT_H__
#define __KBHIT_H__
void init_keyboard(void);
void close_keyboard(void);
int kbhit(void);
int readch(void);
#endif
/*
kbhit.h EOF
*/
/*
Use it like this quick and dirty example
*/
#include <stdlib.h>
#include <stdio.h>
#include "kbhit.h"
int main(void)
{
int ch;
init_keyboard(); // run this once per program
// one way to use it
if(kbhit()) ch = readch();
// here's another sample usage
do {
if(kbhit()) // kbhit returns immediately, key pressed or not
{
ch = readch();
// do whatever here based on value of ch
if(ch='q') break;
}
sleep(1);
} while(1);
close_keyboard();
return 0;
}