tags:

views:

250

answers:

7

Hi, I'm practicing C programming for Linux for an exam. I don't know how to exit the program when user press Ctrl + a ( not Ctrl+c ) For example, looping something until user press Ctrl+a Could anyone tell me how to check Ctrl+a input?

Notes: I'm using 'gcc' and run output with './a.out'

Thanks in advance for everyone!

+2  A: 

There is special support for Ctrl-C, which is translated into a signal by the system. If you want your program to stop as soon as another specific key combination is used, it will be much harder.

  • you will need to check the standard input of your program, and you will need to set the standard input so the inputs are not buffered (otherwise you won't see any input until it is validated by the user pressing "return"). The latter part would be done with a ioctl() call and would not be portable;

  • you will need either threads or polling, none of which is very palatable in C.

There are more interesting things to practice in C than these.

Pascal Cuoq
I am not sure why the downvotes. Is there something wrong in this answer?
Pascal Cuoq
I also don't know why someone downvoted you. Thanks for the answer anyway :)
Devyn
+3  A: 

Turbo C and other implementations of C for Windows had a function call getch() which would read single characters from the keyboard; those would have done what you want.

In POSIX environments, such as are implemented by gcc-compiled programs under Unix/Linux, that functionality isn't directly there.

There's a library called curses which allows C programs to do full-screen output processing, and there is also getch() functionality in curses. This may end up being the simplest answer to your problem. You'll need to read the documentation on curses and link the header files and library into your program.

Carl Smotricz
Xinus
+2  A: 

catching ctrl-c event

This post answers your question

Asoo
A: 

Someone posted first with following code which works for me but I don't know why he deleted his answer.

Original Link : http://www.c.happycodings.com/Gnu-Linux/code18.html

#include <stdio.h>
#include <unistd.h>  /* sleep(1) */
#include <signal.h>

void ex_program(int sig);

int main(void) {
 (void) signal(SIGINT, ex_program);

 while(1)
  printf("sleeping .. ZZZzzzz ....\n"), sleep(1);

 return 0;
}

void ex_program(int sig) {
 printf("Wake up call ... !!! - Catched signal: %d ... !!\n", sig);
 (void) signal(SIGINT, SIG_DFL);
}
Devyn
I've deleted my because I'm not yet sure CTRL+A which signal is created by Ctrl+a.
Adam Matan
there is no difference between ctrl+A and ctrl+a
Michel Kogan
+1  A: 

This will do what you want:

stty intr ^a
./a.out

For extra credit, do the equivalent of "stty intr ^a" using the appropriate library function, e.g. "man termios".

Richard Pennington
Sorry Richard, I can't follow you :( I'm not an advance programmer.
Devyn
What stty (and termios) can do is change the interrupt character from control-C to control-A.
Richard Pennington
It would be helpful to explain what this does; I can tell, but a novice might not. I'm a believer that the man who knows 100% but can communicate 10% is not as useful as the man that knows 50% but can communicate 90%..
PP
Richard, I don't know why you had been downvoted either. Thanks for proposing this alternative.
Pascal Cuoq
By the way, should "ioctl()" have been "tcsetattr()" in my answer?
Pascal Cuoq
@PP: I'm a believer that if you give someone a good hint and they figure out the rest, they'll learn a lot more than if you give them the answer directly. Devyn said this was for an exam.
Richard Pennington
+3  A: 

did you looking for something like this ??? this program won't be stopped since you hit ctrl+A and Enter.

#include <stdio.h>

int main() {
    char a;
    while( a!=1 ) //Ascii code for ctrl + A == 1
    {
        a=getchar();
        printf("still looping ...\n");
    }
    printf( "HA! You pressed CTRL+A\n" );
    return 0;
}

But if you wanna terminate your program just after pressing ctrl+A (without hitting enter after that), here you are:

#include <stdio.h>
#include <ncurses.h>

int main() {
    char a;
    initscr();
    raw();

    while( a!=1 )
        a=getch();

    endwin();
    return 0;
}

for compiling second code using GCC, try this command:

gcc -o program.o -lncurses program.cpp
Michel Kogan
Oh, thank you so much. The program quit when I press Ctrl+a but I don't get the message "Ha! You..."One question is why the program quit and Why 'a' is equal to '1' when I press Ctrl+a?
Devyn
I don't think this is what the OP is looking for. His idea is more like a non-blocking, asynchronous way of checking input from STDIN. Think of it like Ctrl-a generating a signal and that being handled in the program. Correct me if I'm wrong :)
Control characters return an ASCII code equal to the position in the alphabet - so Ctrl+A = 1, Ctrl+C = 3, Ctrl+M = 13 (which is incidently a carriage return), Ctrl+G = 7 (which is incidently a bell or beep).
PP
Thanks. You are amazing!
Devyn
A: 

This is how to set CTRL-A as interrupt to break the process. Notice too that CTRL-C doesn't break it after tcsetattr is called.

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

int main(int argc, char* argv[]) {
    struct termios termios;

    if ( tcgetattr(0, &termios) != -1 ) {
        termios.c_cc[VINTR] = '\x01'; /* CTRL-A */
        if ( tcsetattr(0, 0, &termios) != -1 ) {
            printf("Ready. Press CTRL-A to break this program\n");
            while ( 1 ) {
                printf("*\n");
                sleep(1);
            }
        }
    }
}
dtmilano