Wie kann ich ein Strg-C-Ereignis abfangen?

133

Wie fange ich ein Ctrl+ CEreignis in C ++ ab?

Scott
quelle
Konsolenanwendung, Windows-Anwendung oder was?
GManNickG
7
Welches Betriebssystem Windows, Linux, etc ..
shf301
1
Nun, es ist eine Qt-App, aber ich führe sie während der Entwicklung von der Konsole aus aus. (Dies ist Linux)
Scott

Antworten:

172

signalist nicht der zuverlässigste Weg, da er sich in den Implementierungen unterscheidet. Ich würde empfehlen, zu verwenden sigaction. Toms Code würde jetzt so aussehen:

#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
quelle
1
Ich denke, my_handler sollte int ses als Argument nehmen. sig_tist selbst ein Funktionszeigertyp.
Matthew Marshall
38
<stdlib.h> usw. - es ist C, nicht C ++. In C ++ sollten Sie <cstdlib>
Abyx
8
printf()ist nicht asynchron-signal-sicher, kann also nicht im Signalhandler verwendet werden.
PP
7
Diese Funktionen sind unter Windows nicht verfügbar.
Timmmm
2
wäre schön eine erklärung über sa_maskund zu haben sa_flags.
qed
52

Für eine Windows-Konsolen-App möchten Sie SetConsoleCtrlHandler verwenden , um CTRL+ Cund CTRL+ zu verarbeiten BREAK.

Siehe hier für ein Beispiel.

Chris Smith
quelle
40

Sie müssen das SIGINT- Signal abfangen (wir sprechen von POSIX, oder?)

Siehe @Gab Royers Antwort zur Unterschrift.

Beispiel:

#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
quelle
Ja, es ist POSIX. Ich habe vergessen, der Frage Linux hinzuzufügen.
Scott
2
signal () verhält sich unterschiedlich, je nachdem, ob es dem BSD- oder SysV-Stil folgt. sigaction () ist vorzuziehen.
Asveikau
2
Ich weiß, dass es alt ist, aber dies wird nicht in g ++ (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) 7.4.0 kompiliert. Ich musste ändern void my_handler(sig_t s)zu void my_handler(sig_atomic_t s).
JCmonteiro
1

Ja, das ist eine plattformabhängige Frage.

Wenn Sie ein Konsolenprogramm unter POSIX schreiben, verwenden Sie die Signal-API ( #include <signal.h>).

In einer WIN32-GUI-Anwendung sollten Sie die WM_KEYDOWNNachricht verarbeiten.

Joyer
quelle