C Board  

Go Back   C Board > Platform Specific Boards > Linux Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 04-07-2004, 12:17 PM   #1
GA
 
ichijoji's Avatar
 
Join Date: Nov 2002
Posts: 179
faq: cached input with mygetch()

So I'm trying to put together a little text game at school on their redhat machines, right? I'm using a char buffer with system("clear") to write to the screen and mygetch() from the faq to get input.
Code:
int mygetch() {
  struct termios oldt,
                 newt;
  int            ch;
  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;
}
This function does what I need, except it waits for keyboard input before returning a value. Is there any way to get it to return like 0 or something when there's no input, or maybe a whole other function that does that?
__________________
Illusion and reality become impartiality and confidence.

Last edited by ichijoji; 04-07-2004 at 12:19 PM.
ichijoji is offline   Reply With Quote
Old 04-07-2004, 12:37 PM   #2
& the hat of GPL slaying
 
Thantos's Avatar
 
Join Date: Sep 2001
Posts: 5,732
Hmm not sure if there is a kbhit() for linux or not. But you could use select() on stdin to find out when there is input, however I think that requires the enter key. Might want to change the program to use raw input all the way through and then switch it back before exiting.
Thantos is offline   Reply With Quote
Old 04-07-2004, 01:46 PM   #3
& the hat of GPL slaying
 
Thantos's Avatar
 
Join Date: Sep 2001
Posts: 5,732
Good news

If you change it to raw mode then you select will work without the enter key:

Test program:
Code:
#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(void)
{
  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);

}
I'm sure there can be improvements but hey it works

Last edited by Thantos; 04-07-2004 at 02:45 PM. Reason: Fixing small bug V2 :)
Thantos is offline   Reply With Quote
Old 04-27-2004, 05:50 AM   #4
Registered User
 
Join Date: Apr 2004
Posts: 9
To make this work on Solaris you might also find you need the following:

Code:
	newt.c_lflag &= ~(ICANON|ECHO|IEXTEN);
	/* also set TIME to 0 and MIN to 1 (getc will block until there 
	     is atleast 1 char avalible, and return as soon as there is)*/
	newt.c_cc[VTIME] = 0;
	newt.c_cc[VMIN] = 1;
IEXTEN is a implementation defined extension which seems to be on by default on Solaris and makes bad things (tm) happen, and also Solaris seems to default to VMIN being 4 (haven't actualy confirmed it is 4, but it felt like that, and this fixed it)

Alan
awoodland is offline   Reply With Quote
Old 06-18-2008, 11:36 PM   #5
Registered User
 
Join Date: Jun 2008
Posts: 1
Quote:
Originally Posted by awoodland View Post
To make this work on Solaris you might also find you need the following:

Code:
	newt.c_lflag &= ~(ICANON|ECHO|IEXTEN);
	/* also set TIME to 0 and MIN to 1 (getc will block until there 
	     is atleast 1 char avalible, and return as soon as there is)*/
	newt.c_cc[VTIME] = 0;
	newt.c_cc[VMIN] = 1;
IEXTEN is a implementation defined extension which seems to be on by default on Solaris and makes bad things (tm) happen, and also Solaris seems to default to VMIN being 4 (haven't actualy confirmed it is 4, but it felt like that, and this fixed it)

Alan
Man, thanks for that! I can confirm that the VMIN item needs to be set if compiling on HPUX/Itanium (but not for other OSes like Linux); otherwise, you have to press a key exactly 4 times before one gets recognized!
cniggeler is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Input class project (again) Elysia C++ Programming 41 02-13-2009 10:52 AM
can someone help me with these errors please code included geekrockergal C Programming 7 02-10-2009 02:20 PM
Determining if input is int, double, or char Lucid003 C++ Programming 4 11-16-2005 04:16 PM
EOF messing up my input stream? Decrypt C++ Programming 4 09-30-2005 03:00 PM
FAQ Keyboard Input ? (C++) Malikive FAQ Board 6 11-07-2001 09:30 PM


All times are GMT -6. The time now is 06:04 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22