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


133

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


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

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


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;

}

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.