Thread: kbhit() for linux.

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    66

    kbhit() for linux.

    I only want the program to quit if the user has hit a key and that key corresponds to the ESC key. Otherwise i want it to continue looping.

    This is easlily done in windows(shows below), but is there a function which checks for a key press using linux?

    Code:
    #include <stdio.h>
    #include <conio.h>
    
    #define ESCAPE 27
    
    int main(void)
    {
    
    	int loop = 0;
    	int c;
    
    	while(!loop)
    	{
    		printf("\tIM IN THE LOOPY\n");
    
    		if ( kbhit())
    		{
    			c = getch();
    
    			if ( c == ESCAPE )
    			{
    				printf("YOU HIT ESCAPE...NOW QUITTING");
    				loop = 1;
    			}
    		}
    	}
    }
    thanks
    Last edited by jamie85; 03-17-2005 at 07:46 PM.

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Here you go, enjoy:
    Code:
    #include <stdio.h>
    #include <termios.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    int kbhit(void)
    {
      struct termios oldt, newt;
      int ch;
      int oldf;
    
      tcgetattr(STDIN_FILENO, &oldt);
      newt = oldt;
      newt.c_lflag &= ~(ICANON | ECHO);
      tcsetattr(STDIN_FILENO, TCSANOW, &newt);
      oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
      fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
    
      ch = getchar();
    
      tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
      fcntl(STDIN_FILENO, F_SETFL, oldf);
    
      if(ch != EOF)
      {
        ungetc(ch, stdin);
        return 1;
      }
    
      return 0;
    }
    
    int main(void)
    {
      while(!kbhit())
        puts("Press a key!");
      printf("You pressed '%c'!\n", getchar());
      return 0;
    }
    Code:
    itsme@dreams:~/C$ ./kbhit
    Press a key!
    Press a key!
    Press a key!
    Press a key!
    .
    .
    .
    Press a key!
    Press a key!
    Press a key!
    Press a key!
    Press a key!
    You pressed 'r'!
    itsme@dreams:~/C$
    If you understand what you're doing, you're not learning anything.

  3. #3
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    from my post on http://cboard.cprogramming.com/showt...ighlight=kbhit
    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);
    
    }

  4. #4
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Thantos' method will probably work a little bit better. There's a little bug in mine where if you press a key when the program isn't at the right point, the character will echo to the screen when it's not supposed to.
    If you understand what you're doing, you're not learning anything.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Why don't you just use the curses library to do it?

    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by quzah
    Why don't you just use the curses library to do it?

    Quzah.
    Where's your sense of adventure?
    If you understand what you're doing, you're not learning anything.

  7. #7
    Registered User
    Join Date
    Mar 2004
    Posts
    66
    Quote Originally Posted by quzah
    Why don't you just use the curses library to do it?

    Quzah.
    Im considering that now seeing as im using curses throughtout my program anyway.

    Thats for the code guys.

  8. #8
    Registered User
    Join Date
    Mar 2004
    Posts
    66
    Cant seem to implement either of those examples.
    Code:
    		changemode(1);
    
    		if( kbhit() )
    		{
    			ch = getchar();
    			printf("\nGot %c\n", ch);
    
    			if ( ch == 'c')
    			return 1;
    
    			changemode(0);
    
    		}
    This never seems to return to the calling function.
    Do you know any function i can use fom curses for this?

    Thanks

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    You're changing the mode back to 0 after the first call to kbhit(). Does that make any logical sense to you? Look how Thantos implemented it. Does he change the mode back to 0 inside the kbhit() loop? He doesn't. That should tell you something.
    If you understand what you're doing, you're not learning anything.

  10. #10
    Registered User
    Join Date
    Mar 2004
    Posts
    66
    Code:
    ...
    	while (  *ai_mode != FOLLOW_LINE )
    	{
    		printf("\n\njoymode\n\n");
    
    		move_motors_with_stick(device, subdevice_an_zero, subdevice_an_one, x_scale, y_scale, x_min_read, y_min_read, x_max_read, y_max_read);
    
    		read_digital(subdevice_dig, device, &digital_input);
    
    		/* if MARCO has gone over a line, we leave the loop and return to the menu, selecting the follow_ilne module */
    		if (( digital_input & LEFT_SENSOR ) || ( digital_input & RIGHT_SENSOR ))
    		{
    			*ai_mode = FOLLOW_LINE;
    		}
    
    		retval = bla();
    
    		printf("...................%d.....................", retval);
    
    		if ( retval == 1 )
    		{
    			puts("BLA");
    			return 0;
    		}
    
    	}
    
    	return 1;
    
    }
    int bla()
    {
      	int ch;
      	changemode(1);
    
    	if ( kbhit() )
    	{
    
    		changemode(0);
    		return 1;
    
    	}
    
    
    	changemode(0);
      	return 0;
    }
    for some reason, after "BLA" is outputted on the console, it doesnt return to the calling function. Why is this?

    thanks

  11. #11
    Registered User
    Join Date
    Nov 2008
    Posts
    5
    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <termios.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    int kbhit(void)
    {
      struct termios oldt, newt;
      int ch;
      int oldf;
    
      tcgetattr(STDIN_FILENO, &oldt);
      newt = oldt;
      newt.c_lflag &= ~(ICANON | ECHO);
      tcsetattr(STDIN_FILENO, TCSANOW, &newt);
      oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
      fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
    
      ch = getchar();
    
      tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
      fcntl(STDIN_FILENO, F_SETFL, oldf);
    
      if(ch != EOF)
      {
        ungetc(ch, stdin);
        return 1;
      }
    
      return 0;
    }
    
    
    main( int argc, char** argv )
    {
    	char *input = argv[0];
    	int nomor = argc;
    	pid_t pid = 0;
    	/* set stuff up */
    	/* accept command line args */
    	
    	pid = fork();
    	if( pid == 0 ){
    		/* this is the "background" process.  Execute process loop here */
    		int x=0;	
    		while(1)
    		{
    			if(kbhit())
    			  printf("you hit keyboard");
    		}
    	}
    	else {
    		/* "foreground" process exits */
    		exit(0);
    	}
    }
    why this kbhit doesnt work in child process??

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 11-30-2007, 09:46 AM
  2. kbhit() for enter key? not working
    By yahn in forum C++ Programming
    Replies: 4
    Last Post: 04-03-2006, 02:44 AM
  3. implicit declaration of int kbhit(...);
    By Blizzarddog in forum C++ Programming
    Replies: 14
    Last Post: 11-13-2003, 05:39 PM
  4. Pausing for input, with kbhit() still detecting keys
    By Da-Spit in forum C++ Programming
    Replies: 5
    Last Post: 05-23-2002, 05:04 AM
  5. need more help on kbhit()
    By lordvlaad() in forum C++ Programming
    Replies: 0
    Last Post: 04-20-2002, 02:07 AM