如何捕捉ctrl-c事件?


Answers:


172

signal不是最可靠的方法,因为它在实现上有所不同。我建议使用sigaction。Tom的代码现在看起来像这样:

#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 2010年

8
printf()不是异步信号安全的,因此不能在信号处理程序中使用。
PP

7
这些功能在Windows上不可用。
Timmmm '17

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消息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.