Search code examples
c++linuxgetchar

debian linux c++ how to make key stroke brake infinit loop


I want a infinit loop to break when I press "q" key on my keyboard. Problems I did'nt realize: standard getchar waits for the user to make an input and press enter, which halt the execution of the loop there.

I got around the "enter" problem, but the loop still halts and waits for the input.

here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <termios.h>

int getch(void); // Declare of new function

int main (void) { char x;

do 
{ 
   if (x = getch())
      printf ("Got It! \n!); 
   else 
   { 
      delay(2000);
      printf ("Not yet\n!); 
   }

}while x != 'q');

return 0;
}


int getch(void)
{
int ch;
struct termios oldt;
struct termios newt;

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;
}

Solution

  • I had to do following to make it work correctly, thanks for input!!

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <stdint.h> 
    #include <unistd.h> 
    #include <termios.h> 
    #include <fcntl.h>
    
    int getch(void); // Declare of new function 
    
    int main (void) 
    { 
    
    char x; 
    
    do  
    {  
    x = getch();
            if (x != EOF)
            {
                printf ("\r%s\n", "Got something:");
                printf ("it's %c!",x); //  %c - for character %d - for ascii number   
    }else  
       {  
          delay(2000); 
          printf ("Not yet\n!);  
       } 
    
    }while x != 'q'); 
    
    return 0; 
    } 
    
    
    int getch(void)
    {
        int ch;
        struct termios oldt;
        struct termios newt;
        long oldf;
        long newf;
    
        tcgetattr(STDIN_FILENO, &oldt);             /* Store old settings */
        newt = oldt;
        newt.c_lflag &= ~(ICANON | ECHO);           /* Make one change to old settings in new settings */
        tcsetattr(STDIN_FILENO, TCSANOW, &newt);    /* Apply the changes immediatly */
    
        oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
        newf = oldf | O_NONBLOCK;
        fcntl(STDIN_FILENO, F_SETFL, newf);
    
        ch = getchar();
        fcntl(STDIN_FILENO, F_SETFL, oldf);
        tcsetattr(STDIN_FILENO, TCSANOW, &oldt);    /* Reapply the old settings */
        return ch;
    }