Come posso catturare un evento ctrl-c?


133

Come posso catturare un evento Ctrl+ Cin C ++?


Applicazione console, applicazione Windows o cosa?
GManNickG

7
Quale sistema operativo Windows, Linux, ecc.
shf301,

1
Bene, è un'app Qt, ma la sto eseguendo dalla console durante lo sviluppo. (Questo è Linux)
Scott,

Risposte:


172

signalnon è il modo più affidabile in quanto differisce nelle implementazioni. Consiglierei di usare sigaction. Il codice di Tom ora dovrebbe apparire così:

#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
Penso che my_handler dovrebbe prendere int scome argomento. sig_tè esso stesso un tipo di puntatore a funzione.
Matthew Marshall,

38
<stdlib.h>, ecc. è C, non C ++. In C ++ dovresti usare <cstdlib>
Abyx il

8
printf()non è sicuro per il segnale asincrono, quindi non può essere utilizzato all'interno del gestore del segnale.
PP,

7
Queste funzioni non sono disponibili su Windows.
Timmmm,

2
sarebbe bello avere qualche spiegazione su sa_maske sa_flags.
Q


40

Devi catturare il segnale SIGINT (stiamo parlando POSIX giusto?)

Vedi la risposta di @Gab Royer per la sigazione.

Esempio:

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

}

Sì, è POSIX. Ho dimenticato di aggiungere Linux alla domanda.
Scott,

2
signal () si comporta diversamente, a seconda che segua lo stile BSD o SysV. è preferibile la sigazione ().
asveikau,

2
So che è vecchio, ma questo non viene compilato in g ++ (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) 7.4.0. Ho dovuto cambiare void my_handler(sig_t s)in void my_handler(sig_atomic_t s).
jcmonteiro,

1

Sì, questa è una domanda dipendente dalla piattaforma.

Se stai scrivendo un programma console su POSIX, usa l'API di segnale ( #include <signal.h>).

In un'applicazione GUI WIN32 è necessario gestire il WM_KEYDOWNmessaggio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.