2016-06-28 70 views
0

我必须在while循环中从用户处获得输入,然后采取一些措施。而且我也想在ctrl + c输入中退出我的代码。使用scanf循环处理SIGINT

void my_signal_handler(int sig) 
{ 
    running = false; 
    signal(sig, SIG_IGN); 
} 
int main(void) 
{ 
    struct sigaction sa = {{0}}; 
    sa.sa_handler = &my_signal_handler; 
    sigemptyset(&sa.sa_mask); 
    sa.sa_flags = 0; 

    if (sigaction(SIGINT, &sa, NULL) != 0) 
    { 
     fprintf(stderr, "sigaction error\n"); 
     return -1; 
    } 
    while(running) 
    { 
     printf("enter number: "); 
     scanf("%d", &num); 
     // take action based on number 
    } 
} 

问题的这个代码是按CTRL + C,它不退出之后,但它等待针对scanf的输入。所以一旦我按下一个额外的键,程序就会退出(信号处理程序被调用)。

如何在按下ctrl + c后删除这个给scanf输入的额外步骤?

+0

你可以通过激励来改善你的问题吗(所以请**编辑你的问题**)? –

+0

顺便说一下,给定的代码不会编译。 'scanf(%d“中有一个双引号缺失,&num);' –

回答

1

您应该安装信号处理程序。最起码,加

signal(SIGINT, my_signal_handler); 

里面你mainwhile(running),而是更好地利用sigaction(2)前。

你也应该知道stdiobuffering;通常stdout在终端时是线路缓冲的(但请参阅setvbuf(3)和朋友)。因此,您应该在循环内的scanf之前呼叫fflush(3)(可能为fflush(NULL);),或者以明确的\n终止每个printf格式控制字符串。

最后,scanf(3)可能会失败并返回您应该测试的扫描项目的计数。

顺便说一句,您的main是错误的,应该定义为int main(void)或最好是int main(int argc, char**argv)

但是(假设你是在Linux上),读得很仔细​​(注意什么说一下信号处理程序和异步信号安全功能)和POSIX signal.h documentation并宣布你running标志作为

volatile sigatomic_t running; 

(或也许在C11中,如volatile _Atomic bool running;

volatile qualifier非常重要。否则,允许编译器优化(并假设running总是为真)。

请注意,使用signal(2)通常是一个坏主意。首先,如果你真的需要信号处理,你最好使用sigaction(2)。那么你的电话signal(sig, SIG_IGN);,在你的情况下,是无用的(因为running挥发性标志将在信号处理程序中更改)。最后,对于多路复用输入(&输出),您可以使用poll(2),它可用于等待并测试stdin(实际上STDIN_FILENO是0)是否存在某些可用输入,并且更一般地用于执行event loops。您可以使用(而不是poll,我强烈建议)旧的和几乎过时的select(2),但您宁可使用poll(2)。另请参阅epoll(7) & inotify(7)但您可能不需要它们。

请注意,在终端,stdin往往是继line discipline一个TTY(检查与isatty(3))(所以一些行缓冲的情况内核)。阅读tty demystified页面。考虑使用GNU readline库和函数(或者可能是ncurses),这可能是你真正需要的。

另请参阅Advanced Linux Programming并养成阅读您正在使用的每个函数的文档的习惯。

+0

实际上,在行信号处理程序配置中,我已经为sigaction添加了适当的代码,我将再次更新代码以显示我的actual_code。 – Patrick

+0

@BS你可以显示这一行的代码示例“多路复用输入(&输出),你可以使用poll(2),它可以用来等待和测试stdin上是否有一些可用的输入(实际上是STDIN_FILENO,它是0)。” – Patrick

+0

这可能需要我太多时间(特别是如果你对Linux编程不太熟悉),我提供了参考资料,特别是ALP书籍 –