6

Program:

#include<stdio.h>
void main()
{
    int time=1800;
    while(1){
        system("clear");
        time-=1;
        printf("%d\n",time);
        sleep(1);
    if(time==0)
        pause();
    }
}

The above program stops when the time reaches 0. My requirement is during the runtime of the program, If I press any key like spacebar or any other key, the program gets paused and once again I press the key, the program gets resumed. So for doing this, before execution of while condition, we submit the signal handler for keyboard interrupt. In C how to do this.

What is the function used to get keyboard interrupt. I dont want to get input from the user, I want to handle the interrupt generated by the user through keyboard.

Thanks in Advance..,

mohangraj
  • 9,842
  • 19
  • 59
  • 94
  • What Operating System? – kaylum Sep 04 '15 at 05:40
  • 1
    use sighandler_t signal(int signum, sighandler_t handler); – venki Sep 04 '15 at 05:45
  • There is a library signal.h to use signals and their handling. Use that and ^this. – vish4071 Sep 04 '15 at 05:47
  • 2
    @venki and vish4071 Please expand on how signals can be used to get keyboard presses. There isn't a way that I know of. Signals can be used to catch certain key combinations such as ctrl-c. But the question seems to be about getting arbitrary key presses. – kaylum Sep 04 '15 at 05:55
  • 1
    On Linux you can receive key presses via the Input subsystem. Read about it [here](https://www.kernel.org/doc/Documentation/input/input.txt). Basically an input device is opened such as `/dev/input/event0` which corresponds to the keyboard device. Then events can be read from that device. Each key press and release will generate an event. – kaylum Sep 04 '15 at 05:58
  • ctrl and c are not keyboard keys? – venki Sep 04 '15 at 06:11
  • I want to handle the interrupt generated by the user through keyboard what does this line means – venki Sep 04 '15 at 06:12
  • @venki They are keyboard keys. But they are not the **only** keyboard keys. Simple example, how to get a signal when the user presses space bar? – kaylum Sep 04 '15 at 06:13
  • spacebar will not generate interrupt check question again – venki Sep 04 '15 at 06:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/88754/discussion-between-venki-and-alan-au). – venki Sep 04 '15 at 06:30
  • 1
    mohan + @alanau: http://www.makelinux.net/ldd3/chp-6-sect-4 – rici Sep 04 '15 at 07:33

3 Answers3

4

The keyboard does not exist in purely standard C99 or C11 (stdin is not a keyboard, and could be a pipe(7) so is not always a tty(4); you might read from /dev/tty ...).

So it is much less simple that what you want it to be, and it is operating system specific. I am focusing on Linux.

Read much more about ttys, notably read the tty demystified. Notice that tty are usually in cooked mode, where the kernel is buffering lines (in addition of stdin being line buffered).

The reasonable way is to use a terminal library like ncurses or readline. These libraries are setting the tty in raw mode (which you might do by yourself, see this and termios(3); you'll probably need also to poll(2)). Be sure to exit properly and reset the tty to cooked mode before exiting.

But your life is probably too short to dive into termios(3) and tty_ioctl(4) so just use ncurses or readline

You could also consider some GUI application (e.g. above X11 or Wayland). Then use a toolkit (GTK, Qt, ...).

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
4

You need conio.h for your requirement.It defines kbhit() and getch() both wait for input from keyboard.

Whenever kbhit() is called, it checks the keyboard buffer and returns a nonzero value if the buffer has any keypress otherwise 0 is returned.

The conio.h is used by MSDOS compilers and is not the part of standard C libraries (ISO). It is also not defined in POSIX.

#include<stdio.h>
#include<conio.h>

int main()
{
   while(1)
   {
       while(!kbhit())
       {
          //works continuously until interrupted by keyboard input.
          printf("M Tired. Break Me\n");
       }
       getch();
   }
   return 0;
}

For linux you may use the following snippet to implement kbhit() by using fnctl() from fnctl.h for signal handling:

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

My requirement is during the runtime of the program, If I press any key like spacebar or any other key, the program gets paused and once again I press the key, the program gets resumed.

You can achieve this with this type of code

#include <stdio.h>
int main()
{
  char i;int y=0;
  while(1)
  {
     if(!(_kbhit()))
     {
       y=0;
       printf("//key is not pressed");
       //do what you want
     }
     else
     {
       printf("key pressed (execution pause) , press again to resume");
       i=_getch();
       y=1;
     }
     if(y==1)
     {
       getch();
     }
  }
  return 0;
}
udit043
  • 1,610
  • 3
  • 22
  • 40