【问题标题】:How to limit in 2 mins time the program execution in C [closed]如何在 2 分钟内限制 C 中的程序执行时间 [关闭]
【发布时间】:2013-08-21 14:49:01
【问题描述】:

我没有任何代码,但假设用户应该在 2 分钟内回答数学问题并生成它的分数:

样本输出1:

1+2 = *user's answer*
1+5 = *user's answer*
5+6 = *user's answer*
9+0 = *user's answer*
5+8 = *user's answer*
2+9 = *user's answer*

Time: 0:2:0:0                                                                                 
Time's up!                                                                                   
Your score: 6 

样本输出2:

1+2 = *user's answer*
1+5 = *user's answer*
5+6 = *user's answer*
9+0 = *user's answer*


Time: 0:2:0:0                                                                                
Time's up!                                                                                  
Your score: 4 

代码:

void add()  //Addition
{
    int x,num,num2,ans,sum,score=0;
    time_t t;

    clrscr();

    for(x=0;x<5;x++) // I tried for(x=0;x<=time();x++) but compiled error
    {
        srand((unsigned) time(&t));
        num=rand()%9;
        num2=rand()%9;
        sum=num+num2;

        gotoxy(30,14);
        clrscr();
        printf("\n%d + %d = ",num,num2);
        printf("\nAns: ");
        scanf("%d",&ans);

        if(ans==sum)
        {
            score++;
        }
        else
        {
        printf("\nengggk!!!\n");
        }

    }

    printf("\n\t\t\t ....Your score: %d",score);
    pass(score);
}

void time()
{
    int h,m,s;

    clrscr();
    for(h=0;h<12;h++)
    {
        for(m=0;m<60;m++)
        {
            for(s=0;s<60;s++)
            {
                 printf("TIMER::\n%d:%d:%d",h,m,s);

             if(m==2)
             {
                     printf("Time's up!");
                     pass();
                 return m;
                 }
             }
         }

}

我真的不知道该怎么做,请帮助我。

谢谢。

【问题讨论】:

  • 请正确缩进您的代码。
  • 好的 :) 对不起,我是新手
  • 从您的代码的外观来看,您使用的是非常旧的编译器(可能是 Turbo C 或类似的)。如果你使用更新的东西,你会得到更好的结果。
  • 是的,这是我的教授要求我们使用的

标签: c


【解决方案1】:

假设一个足够类似于 POSIX 的系统,您可以使用alarm() signal() 或(更好) sigaction()。概述:

static volatile sig_atomic_t alarmed = 0;

static void alarm_handler(int signum)
{
    signal(signum, alarm_handler);  // Uses signum — probably not strictly necessary
    alarmed = 1;
}

...

signal(SIGALRM, alarm_handler);
alarm(2*60);

if ((nbytes = read(line, sizeof(line), STDIN_FILENO)) > 0)
{
    ...process normal answer...
}
else if (nbytes == 0)
    ...process EOF...
else if (errno == EINTR)
    ...check whether alarm went off — alarm_handler should set a flag...
else
    ...something broke — report error...

鉴于您可能正在使用标准 I/O,您将​​ read() 更改为 fgets() 并使用 feof() 检查 EOF,您可以假设您遇到了错误而不会打扰 ferror() 并执行errno 检查。在调用 I/O 函数之前,您可能更愿意将 errno 设置为 0;不过,这并不是绝对必要的。

您可以随时拨打alarm(0);取消闹钟。


我开始挖掘我的一个名为timeout 的程序,它运行另一个命令并等待它完成——但如果它完成得不够快,它就会超时。在 cmets 中有一些注释可能会对您有所帮助:

/*
** On MacOS X, the signal() function is implemented using sigaction()
** and includes SA_RESTART in the options, so that when the alarm times
** out, the signal catcher is called but wait() resumes, which is
** not what's wanted.  Hence, upgrade to use sigaction() directly (when
** available; assume it is available by default) without the SA_RESTART.
*/
static void set_interruptible_alarm_handler(void (*handler)(int))
{
#ifdef NO_SIGACTION
    /* Unlikely to be necessary on modern POSIX systems */
    signal(SIGALRM, catcher);
#else
    struct sigaction act;

    if (sigemptyset(&act.sa_mask) != 0)
        err_syserr("sigemptyset failed: ");
    act.sa_handler = handler;
    act.sa_flags = 0;
    if (sigaction(SIGALRM, &act, 0) != 0)
        err_syserr("failed to set signal handler\n");
#endif /* NO_SIGACTION */
}

使用sigaction()signal()更冗长,但控制更好。

【讨论】:

  • 谢谢你.. 我希望它会运行 :) 非常感谢
【解决方案2】:

您不能使用标准设施。输入函数会阻塞,直到您收到输入,然后您才能再次执行代码。所以你有两个选择:

  1. 在等待输入之前花点时间。收到输入后,再花点时间,如果用户花的时间过长,则拒绝回答。

  2. 使用不同的输入系统。例如,您可以使用 Boost.Asio 来做到这一点,尽管它并不完全是微不足道的。

https://github.com/rtsuk/liaw2013/wiki/5.3-how-to-time-the-user

【讨论】:

  • 也可以通过为计时创建单独的线程并让它中断输入线程来完成。
  • 不会在我的编译器中运行 :( 还有其他不复杂的选项吗?
  • @JasminAlarilla 很遗憾,没有。
  • @SebastianRedl 你不能从用户空间调用信号让内核中断线程?
  • 查看alarm 会在这么多秒后生成SIGALRM
【解决方案3】:

正如您所说,您使用的是 Turbo C,您可以使用 kbhit()
Documentation Here

它是一个不可移植的函数,但在 Turbo C 世界中,它会返回一个最近按下的键,或者为零。

所以你可以把它放在一个循环中,检查当前时间,以及是否按下了键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    相关资源
    最近更新 更多