Scanf 不等待输入 [英] Scanf is not waiting for input

查看:80
本文介绍了Scanf 不等待输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 scanf 等待输入.但是在我编写的这个程序中,它正在打印你好 无限循环.不是等我进去.

#include #include #include #include #includevoid timer_handler (int signum){静态整数计数 = 0;printf ("定时器已过期 %d 次\n", ++count);}int主(){struct sigaction sa;struct itimerval 计时器;memset (&sa, 0, sizeof (sa));sa.sa_handler = &timer_handler;sigaction (SIGALRM, &sa, NULL);timer.it_value.tv_sec = 0;timer.it_value.tv_usec = 250000;/* ... 之后每 250 毫秒.*/timer.it_interval.tv_sec = 1;timer.it_interval.tv_usec = 250000;/* 启动一个虚拟定时器.每当这个过程发生时,它就会倒计时执行.*/setitimer (ITIMER_REAL, &timer, NULL);/* 做繁忙的工作.*/int i=0;而(1){scanf("%d",&i);//****不等待输入****printf("你好");}}

输出:

<前>定时器超时 1 次你好计时器过期2次你好计时器已过期 3 次你好计时器已过期 4 次你好计时器已过期 5 次你好计时器已过期 6 次你好定时器已过期 7 次

为什么?

?

解决方案

POSIX 平台上的 scanf 函数在其实现中的某处使用了 read 系统调用.当定时器信号发生时,read 调用将被中断并返回一个错误(EINTR),进而导致scanf 也返回.您可以通过检查 scanf 返回 的内容来检查这一点.在这种情况下,它应该返回 EOF 并且 errno 仍然设置为 EINTR.

对此的一个简单解决方案是请求信号重新启动被中断的系统调用.这是通过在 sigaction 结构 sa_flags 成员中添加 SA_RESTART 标志来完成的:

sa.sa_flags = SA_RESTART;

更多信息可以在例如此 POSIX sigaction 参考.>

I know scanf waits for input. But in this program I have written it is printing hello in an infinite loop. Its not waiting for me to enter.

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include<unistd.h>

void timer_handler (int signum)
{
 static int count = 0;
 printf ("timer expired %d times\n", ++count);
}

int main ()
{
 struct sigaction sa;
 struct itimerval timer;


 memset (&sa, 0, sizeof (sa));
 sa.sa_handler = &timer_handler;
 sigaction (SIGALRM, &sa, NULL);


 timer.it_value.tv_sec = 0;
 timer.it_value.tv_usec = 250000;
 /* ... and every 250 msec after that. */
 timer.it_interval.tv_sec = 1;
 timer.it_interval.tv_usec = 250000;
 /* Start a virtual timer. It counts down whenever this process is
   executing. */
 setitimer (ITIMER_REAL, &timer, NULL);

 /* Do busy work. 
 */
 int i=0;
 while(1){
    scanf("%d",&i);      //****Not waiting for input****
    printf("hello");   
}
}

Output :

timer expired 1 times
hello timer expired 2 times
hello timer expired 3 times
hello timer expired 4 times
hello timer expired 5 times
hello timer expired 6 times
hello timer expired 7 times

Why ?

?

解决方案

The scanf function on POSIX platforms somewhere in its implementation is using the read system call. When the timer signal is happening then the read call will be interrupted and return with an error (EINTR), which in turn leads to scanf returning as well. You can check this by checking what scanf returns. In this case it should return EOF with errno still set to EINTR.

A simple solution to this is to ask the signal to restart the interrupted system call. This is done by adding the SA_RESTART flag in the sigaction structures sa_flags member:

sa.sa_flags = SA_RESTART;

More information can be found in e.g. this POSIX sigaction reference.

这篇关于Scanf 不等待输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆