2

我正在制作一个测验程序。所以我想要的是每当用户提出任何问题时,他有 30 秒的时间来回答它。在这 30 秒内,我希望以 1 秒的间隔发出哔声('\a')。现在我想要的是,一旦用户输入任何输入,这种哔声就应该停止。我创建了这个小函数来产生 30 秒的哔声void beep(){ for(int i=0;i<30;i++){cout<<"\a"; Sleep(1000); } } 但是我不知道如何在用户输入他/她的答案后立即停止它,因为一旦我调用它,在它结束之前什么都做不了。任何人都可以提供任何解决方法吗?

4

4 回答 4

1

Disclaimer: I'm not a Windows programmer, I don't know if this is good style or even if it will compile or work. I can't test it here. However, as no one else has given a solution, it's a starting point. I'll edit this answer as I learn more, and hopefully someone who knows more about this will turn up.

Edit: I faked out _kbhit() to a trivial function returning false, and it at least compiles and looks like it runs ok

Edit: Ok I do have ms visual studio at work, I just never use it. The code as it is right now compiles and works (I suspect the timing is off though).

Edit: Updated it to immediately read back the key that was hit (rather than waiting for the user to hit enter).

This is the important function: http://msdn.microsoft.com/en-us/library/58w7c94c%28v=vs.80%29.aspx

#include <windows.h>
#include <conio.h>
#include <ctime>
#include <iostream>
#include <string>

int main()
{
    time_t startTime, lastBeep, curTime;
    time(&startTime);
    lastBeep = curTime = startTime;
    char input = '\0';

    while ( difftime(curTime,startTime) < 30.0 )
    {
        if ( _kbhit() ) // If there is input, get it and stop.
        {
            input = _getch();
            break;
        }
        time(&curTime);
        if ( difftime(curTime,lastBeep) > 1.0 ) // More than a second since last beep?
        {
            std::cout << "\a" << "second\n" << std::flush;
            lastBeep = curTime; // Set last beep to now.
        }
    }
    if ( input )
    {
        std::cout << "You hit: \"" << input << "\"\n" << std::flush;
    }

    return 0;
}
于 2012-08-02T13:37:09.760 回答
1

你需要做一个循环来维持某处的“开始时间”,每 1 秒就发出哔哔声,并继续检查是否有有效的输入。如果 30 秒过去或给出有效输入,则退出。(或输入错误)

伪:

start=now();
lastbeep=start;
end=start+30secs
noanswer=true
while(now()<end&&noanswer)
{
   sleep(100ms)
   noanswre=checkforanswerwithoutblocking();
   if(now()-lastbeep>1sec)
   {
      beepOnce();lastbeep+=1sec;
   }
}
checkIfAnswerIsCorrect();
doStuff();
于 2012-08-02T13:15:07.797 回答
1

我可以建议的粗略的是

void beep() { 
   char press = 'n';
   for(int i = 0; i < 30; i++)
       for(int j = 0; j < 100; j++) {     
           if(press == 'y') return;
           cout << "\a";
           Sleep(10);
       }
    }
}
于 2012-08-02T13:18:40.990 回答
-1

对于窗户: #include <windows.h> ... Beep(1480,200); // for example. ...

Beep() 在内核中的单独线程中执行(据我所知),所以你可以不关心多线程 - 当它执行时,你的 profram 可以检查输入,或者输入新问题,例如

于 2012-08-02T13:15:03.433 回答