Como posso pegar um evento ctrl-c?

133

Como eu pego um evento Ctrl+ Cem C ++?

Scott
fonte
Aplicativo de console, aplicativo do Windows ou o quê?
GManNickG 29/10/09
7
Qual SO Windows, Linux, etc ..
shf301
1
Bem, é um aplicativo Qt, mas estou executando-o no console durante o desenvolvimento. (Este é o Linux)
Scott

Respostas:

172

signalnão é a maneira mais confiável, pois difere nas implementações. Eu recomendaria usar sigaction. O código de Tom agora ficaria assim:

#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
fonte
1
Eu acho que my_handler deve tomar int scomo argumento. sig_té em si um tipo de ponteiro de função.
Matthew Marshall
38
<stdlib.h>, etc - é C, não C ++. Em C ++, você deve usar <cstdlib>
Abyx
8
printf()não é seguro para sinal assíncrono, portanto não pode ser usado dentro do manipulador de sinal.
PP
7
Essas funções não estão disponíveis no Windows.
Timmmm
2
seria bom ter alguma explicação sobre sa_maske sa_flags.
qed
52

Para um aplicativo de console do Windows, você deseja usar SetConsoleCtrlHandler para manipular CTRL+ Ce CTRL+ BREAK.

Veja aqui um exemplo.

Chris Smith
fonte
40

Você tem que pegar o sinal SIGINT (estamos falando de POSIX, certo?)

Veja a resposta de @Gab Royer para sigação.

Exemplo:

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

}
Tom
fonte
Sim, é POSIX. Esqueci de adicionar o Linux à pergunta.
295 Scott Scott
2
O sinal () se comporta de maneira diferente, dependendo do estilo BSD ou SysV. sigaction () é preferível.
Asveikau 29/10/09
2
Eu sei que é antigo, mas isso não compila no g ++ (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) 7.4.0. Eu tive que mudar void my_handler(sig_t s)para void my_handler(sig_atomic_t s).
jcmonteiro
1

Sim, essa é uma pergunta dependente da plataforma.

Se você estiver escrevendo um programa de console no POSIX, use a API de sinal ( #include <signal.h>).

Em um aplicativo GUI do WIN32, você deve manipular a WM_KEYDOWNmensagem.

Joyer
fonte