Як я можу зафіксувати подію ctrl-c?


Відповіді:


172

signalне є найнадійнішим способом, оскільки він відрізняється реалізацією. Я б рекомендував використовувати sigaction. Код Тома тепер виглядатиме так:

#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
Я думаю, my_handler повинен сприйматись int sяк аргумент. sig_tсам по собі тип покажчика функції.
Меттью Маршалл

38
<stdlib.h> тощо - це C, а не C ++. У C ++ слід використовувати <cstdlib>
Abyx,

8
printf()не є безпечним для асинхронного сигналу, тому його не можна використовувати всередині обробника сигналу.
ПП

7
Ці функції недоступні в Windows.
Timmmm

2
було б добре мати деякі пояснення щодо sa_maskі sa_flags.
qed


40

Ви повинні зафіксувати сигнал SIGINT (ми говоримо POSIX правильно?)

Дивіться відповідь @Gab Royer щодо сигакції.

Приклад:

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

}

Так, це POSIX. Я забув додати Linux до питання.
Скотт

2
signal () поводиться по-різному, залежно від того, чи він відповідає стилю BSD або SysV. sigaction () є кращим.
asveikau

2
Я знаю, що він старий, але це не компілюється в g ++ (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) 7.4.0. Я повинен був змінити void my_handler(sig_t s)до void my_handler(sig_atomic_t s).
jcmonteiro

1

Так, це питання, яке залежить від платформи.

Якщо ви пишете консольну програму на POSIX, використовуйте сигнал API ( #include <signal.h>).

У програмі WIN32 GUI слід обробляти WM_KEYDOWNповідомлення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.