gpt4 book ai didi

在 C 中导致 gets() 在 SIGINT 时退出

转载 作者:行者123 更新时间:2023-11-30 21:01:40 25 4
gpt4 key购买 nike

我正在编写一个简单的 C 程序,它使用 gets() 函数从键盘一次读取一行文本(循环)。

如果用户按 CTRL-C,循环必须立即退出。我知道如何编写一个 sig 处理程序,它可以设置一个标志来退出循环...但是如何使 gets() 函数在该信号到达时立即返回?

最佳答案

在从标准输入读取数据之前,您应该使用 select() 检查数据是否可用:

void handler (int arg) {
// handle signal
}

int main (void) {
char buf[100];
signal(SIGINT, handler);
do {
fd_set f;
FD_ZERO(&f);
FD_SET(fileno(stdin), &f);
int st = select(fileno(stdin)+1, &f, NULL, NULL, NULL);
if (st == 1) {
fgets(buf, sizeof(buf), stdin);
// Handle input
}
} while (st >= 0);

exit(EXIT_SUCCESS);
}

select() 从信号处理程序返回后将返回 -1 (errno EINTR),而 read() (由(f)gets) 将自动恢复。

对于 Linux,还有另一种使用 sigaction() 的可能性:

void handler (int arg) {
// handle signal
}

int main (void) {
char buf[100], *p;
struct sigaction sa = { .sa_handler = handler, .sa_flags = 0, .sa_mask = 0 };
sigaction(SIGINT, &sa, NULL);

do {
p = fgets(buf, sizeof(buf), stdin);
// handle input
} while (p);
printf("Byebye\n");

exit(EXIT_SUCCESS);
}

由于信号处理程序的 sa_flags 中未指定标志 SA_RESTART,因此 read()/em> 设备(即终端、管道、套接字)也将返回 -1 (EINTR)(另请参阅 signal(7))。

虽然有点简单,但不同的 UNIX 风格(甚至内核版本)之间的行为可能会有所不同,因此第一个版本是一种更安全、更便携/可靠的方式。

关于在 C 中导致 gets() 在 SIGINT 时退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34995207/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com