Thread: while getch question

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    9

    Question while getch question

    Hi,

    I'm trying to write a while loop that is able to recognise and act on keyboard presses without pausing to wait for an input (unlike getchar()).

    At the moment I'm just trying to detect any keypress and exit the loop by changing an integer, printing out the recorded keypress on the way out. Later I'd like to recognise the keypress as part of conditional statements and keep looping.

    Here is the code that I've got so far, it has been modified from an example. Currently the loop just keeps running indefinately, regardless of what I press.

    Some extra information that may be important: this code is a small addition to a large working example (which I am modifying) that runs on a remote embedded PC, I've omitted about 450 lines (including lots of headers) for this snippet. Also, it may be useful to know that I'm accessing the PC via Putty , a telnet / SSH client.

    Code:
    #include <stdio.h> 
    #include <err.h>	
    #include <curses.h> /* for ERR */
    
    int main(){
    
       char chr;	/* Keyboard character */
       int done = 0;	/* while condition */
       
       while (done != 1){
              printf(". ");     /* show that we are looping */
              usleep(5000); /* wait a moment */
              if ((chr = getch()) != ERR) done = 1; /* if anything has been pressed leave the loop*/
       }
    
       printf(" chr = %c\n", chr);  /* show which key was pressed */
    }
    Thanks for reading, any help appreciated,

    Ad

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Are you sure ERR is what you need?
    Devoted my life to programming...

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Are you in no-delay mode? What happens if you press enter?

  4. #4
    Registered User
    Join Date
    Dec 2010
    Posts
    9
    Hi,

    The while loop keeps printing '. ' so it isn't blocking. I assume that means no-delay is true (though I haven't set this explicitly I believe that it is the default).

    If i press enter I get a line break in the output (i.e. .........[\n]......) but the loop doesn't exit. It's the same with any character, it appears in the console but doesn't affect the loop behaviour.

    Thanks,

    Ad

  5. #5
    Registered User
    Join Date
    Dec 2010
    Posts
    9
    Hi,

    I used ERR as this seemed to have been used in the code I've been using as an example. I believed that the statement would return ERR if nothing had been pressed. Is this not a good choice?

    Btw, I have tried the following without success, the loop still doesn't exit.
    if ((chr = getch()) == 'a') done = 1;
    Thanks,

    Ad
    Last edited by Ad_robot; 12-20-2010 at 09:33 AM. Reason: typo

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If your char's are unsigned, and ERR is negative (as I suspect it is), then your comparison will never be true. What if you make chr an int instead of a char?

  7. #7
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    You wait a total of 5 seconds. Your console maynot catch the keyboard hit.
    Devoted my life to programming...

  8. #8
    Registered User
    Join Date
    Dec 2010
    Posts
    9
    Thanks for the suggestions.

    tabstop I've made the chr an integer but I still get the same response.

    Sipher I've reduced usleep to 50 and also taken it out completely but the same response continues. Also, I think usleep(5000) is a wait of 50ms (that seems to be how often the dots appear).

    Ad

  9. #9
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Oh, sorry. I confused usleep with Sleep...
    Devoted my life to programming...

  10. #10
    Registered User
    Join Date
    Dec 2010
    Posts
    9
    Btw, I just checked and ERR is '-1'.

    I put this in my while loop
    printf("\n. %d",getch());
    But even if I hold down a key and make usleep very small, getch = '-1'. Interesting... it seems that my keystrokes aren't being detected by getch?

    Could this be something to do with my remote interface? It seems to work on the demo code that shipped with the system, and that used getch for the input.

  11. #11
    Registered User
    Join Date
    Dec 2010
    Posts
    9
    Aargh, but getchar() detects keys fine! So it's not the remote interface...

  12. #12

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Ad_robot View Post
    Btw, I just checked and ERR is '-1'.

    I put this in my while loop


    But even if I hold down a key and make usleep very small, getch = '-1'. Interesting... it seems that my keystrokes aren't being detected by getch?

    Could this be something to do with my remote interface? It seems to work on the demo code that shipped with the system, and that used getch for the input.
    getch may well be polling the keyboard at the other end and not accepting the keys from PuTTY. (I don't remember, if I ever knew, how those two interrelate.) The easy way to check would be to run this on your box and see what happens (or send someone over there to push buttons on that machine, if possible).

  14. #14
    Registered User
    Join Date
    Dec 2010
    Posts
    9
    tabstop,

    Unfortunately the other system doesn't have a keyboard, mouse or display, it's an embedded platform connected to some sensors and actuators.

    The strange thing is that getchar() does detect the keypresses from my system, so one would assume that getch() would work the same. It seems not.

    I didn't mention that the remote system is running Linux and I'm running Windows. This shouldn't be a problem thought should it?

    Back to reading the ncurses guide...

  15. #15
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Your code needs some curses requirements and you need to set the mode to cbreak. Here's my version with a few comments:
    Code:
    #include <stdio.h>
    #include <unistd.h> // for usleep
    #include <err.h>
    #include <curses.h>
    
    int main(void)
    {
        char chr;
    
        initscr();  // mandatory curses init
        cbreak();   // unbuffered input
        do {
            chr = getch();
        } while (chr == ERR);
    
        printw(" chr = %02x\n", chr);
        refresh();  // show the printf stuff
        getch();    // wait for user input
    
        endwin();   // curses cleanup
    
        return 0;
    }
    EDIT: I should have used curses' printw function instead of printf.
    Last edited by anduril462; 12-20-2010 at 11:30 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie question, C #
    By mate222 in forum C# Programming
    Replies: 4
    Last Post: 12-01-2009, 06:24 AM
  2. a question about putch and getch
    By jackhasf in forum C Programming
    Replies: 3
    Last Post: 10-31-2009, 03:07 PM
  3. Clearing input buffer after using getch()
    By milkydoo in forum C++ Programming
    Replies: 3
    Last Post: 07-21-2003, 11:04 PM
  4. simple question -getch \n and \r
    By GanglyLamb in forum C Programming
    Replies: 1
    Last Post: 06-10-2003, 08:12 AM
  5. opengl DC question
    By SAMSAM in forum Game Programming
    Replies: 6
    Last Post: 02-26-2003, 09:22 PM

Tags for this Thread