【问题标题】:beep sound till any input哔声直到任何输入
【发布时间】:2012-07-31 11:06:34
【问题描述】:

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

【问题讨论】:

  • 听起来像是多线程程序的任务...如果您是 C++ 初学者,我认为这不是一个很好的例子
  • 可能存在不使用线程(或至少不显式使用线程)的平台特定方式。您使用什么操作系统?你愿意使用任何额外的库吗? (不暗示任何特定的解决方案,只是有用的信息)。
  • 我对 windows 不是很感兴趣,但我相信它有一些非阻塞输入功能可用......我会看看,看看我能想出什么。

标签: c++ audio beep


【解决方案1】:

免责声明:我不是 Windows 程序员,我不知道这是否是好的风格,或者它是否可以编译或工作。我不能在这里测试它。但是,由于没有其他人给出解决方案,因此这是一个起点。当我了解更多信息时,我将编辑此答案,希望有更多了解此问题的人出现。

编辑:我将_kbhit() 伪装成一个返回false 的微不足道的函数,它至少可以编译并且看起来运行正常

编辑:好的,我确实有 ms visual studio 在工作,我只是从不使用它。现在的代码可以编译并且可以运行(不过我怀疑时间已经过时了)。

编辑:将其更新为立即回读被击中的键(而不是等待用户按 Enter)。

这是重要的功能: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;
}

【讨论】:

  • main.cpp|8|错误 E2451:函数 main() 中未定义的符号 'time_t'| main.cpp|8|错误 E2379:缺少语句;在函数 main()| main.cpp|9|错误 E2451:函数 main()| 中未定义符号“startTime”| main.cpp|10|错误 E2451:函数 main()| 中未定义符号“lastBeep”| main.cpp|10|错误 E2451:函数 main()| 中未定义的符号“curTime”| main.cpp|13|错误 E2268:在函数 main()| 中调用未定义函数 'difftime' main.cpp|15|错误 E2268:在函数 main() 中调用未定义函数 '_kbhit'|
  • main.cpp|21|错误 E2268:在函数 main() 中调用未定义的函数 'difftime'|
  • 这些是我尝试在代码块上运行它时遇到的错误
  • @Harsh 这看起来像是代码块配置方式中的错误(未找到头文件)。恐怕帮不了你。
  • 我赞成使用_kbhit()。但是,difftime() 在 Windows 上不可用。我建议使用简单的Sleep(100),并且每 10 次迭代就会发出哔哔声。毕竟,这个任务不需要很高的精度,用户在处理输入之前可能不会注意到 100 毫秒的延迟。
【解决方案2】:

您需要做一个循环来维持某处的“开始时间”,每次 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();

【讨论】:

  • 仍然需要绕过阻塞输入。
  • 问题中没有阻塞输入,阻塞哔声是。
  • theres an answer for the non blockign input for c
  • 我真的不明白如何实现这个,代码对我来说似乎很难。对不起,我是新人...你能用简单的方式解释一下吗?
  • 这是最简单的方法。我必须承认,使用 c/c++ 正确实现非阻塞输入似乎非常困难,因此您必须对此进行一些研究。那个伪代码就这么简单。使用线程,您将遇到同步、锁定和线程问题。
【解决方案3】:

我可以建议的粗略的是

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);
       }
    }
}

【讨论】:

  • 这将如何工作? press 是一个不会在任何地方更新的局部变量?
【解决方案4】:

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 2010-12-27
  • 2016-07-18
  • 2012-12-06
  • 2018-08-30
  • 2018-08-11
相关资源
最近更新 更多