【问题标题】:How to terminate scanf after a few seconds?几秒钟后如何终止scanf?
【发布时间】:2020-10-14 02:22:39
【问题描述】:

我在 C 语言中使用信号。该程序包括等待几秒钟以等待用户键盘输入,如果时间结束,则程序终止。但是,我总是必须输入文本,尽管时间已经结束,否则程序永远不会结束。有什么办法可以避免scanf?

这是我的代码

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdlib.h>
#define NSECS 10
#define TRUE 1
#define FALSE 0
# define BELLS "\007\007\007"

int alarm_flag = FALSE;

void bye(){
    printf("Good bye...");
}

void setflag(){
    alarm_flag = TRUE;
}

int main() {
char name[20];
    do {
        

        printf("File name: \n"); 
        scanf("%s", name);

        signal(SIGALRM, setflag);
        alarm(NSECS);
        
        if (alarm_flag == TRUE){
            printf(BELLS);
            atexit(adios); 
            return 0;
        } // if the user enters a file name, the program continues 

           

【问题讨论】:

  • 请添加操作系统标签。
  • @Joshua:我不确定是否有合适的标签——类 Unix?
  • @DietrichEpp:有一个 posix 标签,或者他可以为他实际使用的操作系统添加标签。
  • @Joshua 已更新,感谢推荐

标签: c linux signals posix


【解决方案1】:

你快到了——先设置闹钟,然后打电话给scanf。该信号将中断对scanf() 内部的read() 的调用,从而导致scanf() 立即返回。

volatile int alarm_flag = 0;
void setflag(int sig) {
    alarm_flag = 1;
}

...

struct sigaction act = {};
act.sa_handler = set_flag;
sigaction(SIGALRM, &act, NULL);

...

    alarm(NSECS);
    scanf("%s", name);
    if (alarm_flag) {
        ...

几个注意事项:

  • alarm_flag 应该是volatile

  • setflag 应该带一个int 参数。

  • 将您的函数声明为func(void) 而不是func()。将函数声明为 func() 是 1990 年左右之前的老式风格,今天使用它没有任何好处。 (注意 C++ 是不同的。)

更多注释:

  • 您不应使用== TRUE== FALSE。在这种特殊情况下,它可能工作正常,但在某些情况下却不行。所以我几乎不会使用== TRUE

  • 作为练习,这个带有alarm 的代码是合理的,但是如果您想在生产应用程序中做这种事情,您可能会使用libuv 之类的东西而不是alarm()。并不是这种方法有什么问题错误,只是使用非阻塞 IO 和libuv 可能会更容易处理。

【讨论】:

  • 非常感谢,这个解决方案对我来说效果很好
  • 迂腐:alarm_flag 的类型应该是sig_atomic_t
猜你喜欢
  • 2018-02-25
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 1970-01-01
  • 2014-05-18
  • 1970-01-01
相关资源
最近更新 更多