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

StackOverflow https://stackoverflow.com/questions/21903495

Frage

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);  
War es hilfreich?

Lösung 2

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

Andere Tipps

There are a wide range of ways to do this including that mentioned here however my personal favorite is to use a fork and signal. This is more efficient than non blocking ops (does not waste system calls and thus context switches) on every loop iteration.

Effectively you fork a worker process to perform the loop, install a signal handler for say USR1 into it then have your parent process wait for a keypress blocking, once it receives the wanted key it can send the USR1 signal to the other process which will cause the signal handler to clean it up and terminate.

Please see these for more info:

I shall also note that this solution works for effectively any blocking situation which you could fix using non-blocking IO and will usually save some CPU time, albeit costing a little memory and CPU when creating the fork.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top