c - 如何在几秒钟后终止scanf?

标签 c linux signals posix

我正在使用 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 

           

最佳答案

你就快到了——先设置闹钟,然后调用 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 可能更容易处理。

关于c - 如何在几秒钟后终止scanf?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64345721/

相关文章:

c - 打印字符数组

linux - 使用 AWK 从 csv 文件中提取特定的单元格,并根据预定义的顺序进行排序

C - 获取 token 信息时缓冲打印垃圾字符

使用 autoconf 检查 C#define 的值

python-3.x - 从 Github 安装 Yocto Bitbake podman-py setuptools 失败

Linux 上的 Java : maximize a non-Java GUI application

sigaction 中的 Android _Unwind_Backtrace

c - 如何用C语言编程control+C信号来暂停和取消暂停输出?

c - 包含的头文件是否在C文件中展开

c# - 在使用 Mono 的 Ubuntu 中运行基于 DevExpress 的 ASP.NET Web 应用程序时出错