Làm thế nào tôi có thể bắt sự kiện ctrl-c?


133

Làm cách nào để bắt một sự kiện Ctrl+ Ctrong C ++?


Ứng dụng Console, ứng dụng windows, hay gì?
GManNickG

7
Hệ điều hành Windows, Linux, v.v.
shf301

1
Chà, đó là một ứng dụng Qt, nhưng tôi đang chạy nó từ bảng điều khiển trong quá trình phát triển. (Đây là Linux)
Scott

Câu trả lời:


172

signalkhông phải là cách đáng tin cậy nhất vì nó khác nhau trong việc thực hiện. Tôi khuyên bạn nên sử dụng sigaction. Mã của Tom bây giờ sẽ trông như thế này:

#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
Tôi nghĩ my_handler nên lấy int sđó làm đối số. sig_tbản thân nó là một loại con trỏ hàm.
Matthew Marshall

38
<stdlib.h>, v.v. - đó là C, không phải C ++. Trong C ++, bạn nên sử dụng <cstdlib>
Abyx

8
printf()không an toàn async-signal, vì vậy không thể sử dụng bên trong bộ xử lý tín hiệu.
PP

7
Các chức năng này không có sẵn trên Windows.
Timmmm

2
sẽ là tốt đẹp để có một số giải thích về sa_masksa_flags.
qed


40

Bạn phải bắt được tín hiệu SIGINT (chúng ta đang nói POSIX phải không?)

Xem câu trả lời @Gab Royer hungs cho sigaction.

Thí dụ:

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

}

Vâng, đó là POSIX. Tôi quên thêm Linux vào câu hỏi.
Scott

2
signal () hoạt động khác nhau, tùy theo nếu nó tuân theo kiểu BSD hoặc SysV. sigaction () là thích hợp hơn.
asveikau

2
Tôi biết nó đã cũ, nhưng cái này không biên dịch trong g ++ (Ubuntu 7.4.0-1ubfox1 ~ 18.04.1) 7.4.0. Tôi đã phải thay đổi void my_handler(sig_t s)để void my_handler(sig_atomic_t s).
jcmonteiro

1

Vâng, đây là một câu hỏi phụ thuộc nền tảng.

Nếu bạn đang viết chương trình điều khiển trên POSIX, hãy sử dụng API tín hiệu ( #include <signal.h>).

Trong ứng dụng GUI WIN32, bạn nên xử lý WM_KEYDOWNtin nhắn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.