Comment puis-je attraper un événement ctrl-c?

133

Comment attraper un événement Ctrl+ Cen C ++?

Scott
la source
Application console, application Windows ou quoi?
GManNickG
7
Quel OS Windows, Linux, etc.
shf301
1
Eh bien, c'est une application Qt, mais je l'exécute depuis la console pendant le développement. (Ceci est Linux)
Scott

Réponses:

172

signaln'est pas le moyen le plus fiable car il diffère dans les implémentations. Je recommanderais d'utiliser sigaction. Le code de Tom ressemblerait maintenant à ceci:

#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

void my_handler(int s){
           printf("Caught signal %d\n",s);
           exit(1); 

}

int main(int argc,char** argv)
{

   struct sigaction sigIntHandler;

   sigIntHandler.sa_handler = my_handler;
   sigemptyset(&sigIntHandler.sa_mask);
   sigIntHandler.sa_flags = 0;

   sigaction(SIGINT, &sigIntHandler, NULL);

   pause();

   return 0;    
}
Gab Royer
la source
1
Je pense que my_handler devrait prendre int scomme argument. sig_test lui-même un type de pointeur de fonction.
Matthew Marshall
38
<stdlib.h>, etc - c'est C, pas C ++. En C ++, vous devez utiliser <cstdlib>
Abyx
8
printf()n'est pas async-signal-safe, donc ne peut pas être utilisé dans le gestionnaire de signal.
PP
7
Ces fonctions ne sont pas disponibles sous Windows.
Timmmm
2
serait bien d'avoir des explications sur sa_masket sa_flags.
qed
53

Pour une application console Windows, vous souhaitez utiliser SetConsoleCtrlHandler pour gérer CTRL+ Cet CTRL+ BREAK.

Voir ici pour un exemple.

Chris Smith
la source
40

Vous devez attraper le signal SIGINT (nous parlons de POSIX, non?)

Voir la réponse de @Gab Royer pour sigaction.

Exemple:

#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

void my_handler(sig_t s){
           printf("Caught signal %d\n",s);
           exit(1); 

}

int main(int argc,char** argv)
{
   signal (SIGINT,my_handler);

   while(1);
   return 0;

}
À M
la source
Oui, c'est POSIX. J'ai oublié d'ajouter Linux à la question.
Scott
2
signal () se comporte différemment, selon qu'il suit le style BSD ou SysV. sigaction () est préférable.
asveikau
2
Je sais qu'il est ancien, mais cela ne compile pas dans g ++ (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) 7.4.0. J'ai dû changer void my_handler(sig_t s)pour void my_handler(sig_atomic_t s).
jcmonteiro
1

Ouais, c'est une question dépendante de la plate-forme.

Si vous écrivez un programme console sur POSIX, utilisez l'API de signal ( #include <signal.h>).

Dans une application GUI WIN32, vous devez gérer le WM_KEYDOWNmessage.

Joyer
la source