Search code examples
clinuxloopsnonblockinggetchar

How to print a variable continuously in a loop and terminate with a hit of escape key in C under linux?


Please find the section of code below. I want to print the current value of the variable continuously in a loop. And the loop has to be terminated once I hit escape key. Here the problem is that the execution stops at the getchar function. But I want it to continue and print the value of variable until I hit the escape button.

do
{
     vUpdateVariable();        // routine to update the current value of variable
     printf("Value is %f\r", fVariable); 
     ucKey = getchar();
     usleep(1000);
}while (ucKey != 0x1B);  

Solution

  • I got it worked with the code below. For continuously printing the variable. The stderr had to be used. stdout will flush the buffer when the programmer explicitly asks for it or when it is most convenient, stderr writes the message immediately. Due to the canonical mode of your terminal, you need to hit enter to confirm your user input. Canonical mode has to be disable for non blocking execution of the code. Canonical mode means it always wait for enter to confirms the user input. If that is not your case, nonblock is a function to cater that. I dint figure it out myself. Got the code and explanation from other forums.

    #include<stdio.h>
    #include<curses.h>
    #include<unistd.h>
    #include <termios.h>
    #include <sys/time.h>
    
    #define NB_ENABLE 0x01
    #define NB_DISABLE 0x00
    
    int kbhit()
    {
        struct timeval tv;
        fd_set fds;
        tv.tv_sec = 0;
        tv.tv_usec = 0;
        FD_ZERO(&fds);
        FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
        select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
        return FD_ISSET(STDIN_FILENO, &fds);
    }
    
    void nonblock(int state)
    {
         struct termios ttystate;
         tcgetattr(STDIN_FILENO, &ttystate); //get the terminal state
    
         if (state==NB_ENABLE)
         {
              //turn off canonical mode
              ttystate.c_lflag &= ~ICANON;
              //minimum of number input read.
              ttystate.c_cc[VMIN] = 1;
         }
         else if (state==NB_DISABLE)
         {
               //turn on canonical mode
              ttystate.c_lflag |= ICANON;
         }
         //set the terminal attributes.
         tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
     }
     int main()
     {
          char c,i;
          while(c != 27)
          {
               usleep(10000);
               vUpdateVariable();        // routine to update the current value of variable
               printf(stderr,"Value is %f\r", fVariable);            
               i=kbhit();
               c=fgetc(stdin);
           }
           nonblock(NB_DISABLE);
           return 0;
     }