2

I am making a Quiz program. So what I want is whenever any question in presented before the user, then he has 30 seconds to answer it. And in these 30 seconds I want the beep sound ('\a') at an interval of 1 second. Now I want is that this beep sound should stop as soon as the user enters any input. I have created this small function to produce the beep sound for 30 sec void beep(){ for(int i=0;i<30;i++){cout<<"\a"; Sleep(1000); } } But I don't know how to stop it as soon as the user enters his/her answer because once I call it nothing can be done until its over. Can anyone give any workaround for it?

Pshemo
  • 122,468
  • 25
  • 185
  • 269
Harsh
  • 141
  • 2
  • 9
  • 2
    Sounds like a task for a multi-threaded program... I don't think that this is a good example if you are a beginner in C++ – Дамян Станчев Aug 02 '12 at 13:11
  • There may be platform specific ways without using threads (or at least without explicitly using threads). What operating system are you using? And are you willing to use any extra libraries? (Not hinting at any particular solution, just useful information). – BoBTFish Aug 02 '12 at 13:16
  • I'm not so hot with windows, but I believe it has some non-blocking input functions available... I'll have a look and see what I can come up with. – BoBTFish Aug 02 '12 at 13:22

4 Answers4

1

You need to do a loop which maintains the "beginning time" somewhere, beeps every time 1 sec has gone and keeps checking if there is valid input. and exits if 30secs have gone or valid input is given. (or wrong input)

pseudo:

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();
Markus Mikkolainen
  • 3,397
  • 18
  • 21
  • 1
    Still need to get around blocking input. – BoBTFish Aug 02 '12 at 13:17
  • blockign input wasnt in the question, blocking beep was. – Markus Mikkolainen Aug 02 '12 at 13:19
  • theres an answer for the non blockign input for c – Markus Mikkolainen Aug 02 '12 at 13:21
  • I really don't understand how to implement this and code seems difficult to me.Sorry I am new...Can you explain in a simple way? – Harsh Aug 02 '12 at 13:29
  • That was the simple way. I must admit that implementing non-blockigng input properly with c/c++ seems to be darn difficult so you will have to do some research on that. And that pseudocode is as simple as it gets. With threads you will run into synchronization and locking and threading problems. – Markus Mikkolainen Aug 02 '12 at 13:33
  • Okay, I will try to understand.. Can you tell me what do you mean by now(),noanswer,lastbeep,checkifansweriscorret(),dostuff()? – Harsh Aug 02 '12 at 13:34
  • now() would be the current time. noanswer is a boolean flag, checkifansweriscorrect should check if the answer is correct and dostuff is whatever you need to do after you know that the answer is correct or not. Note that this is pseudocode to show how you how to solve the problem, not real code. – Markus Mikkolainen Aug 02 '12 at 14:01
1

something rough i can suggest is

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);
       }
    }
}
Vega TV
  • 217
  • 2
  • 10
Ratan Kumar
  • 1,640
  • 3
  • 25
  • 52
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;
}
BoBTFish
  • 19,167
  • 3
  • 49
  • 76
  • main.cpp|8|Error E2451 : Undefined symbol 'time_t' in function main()| main.cpp|8|Error E2379 : Statement missing ; in function main()| main.cpp|9|Error E2451 : Undefined symbol 'startTime' in function main()| main.cpp|10|Error E2451 : Undefined symbol 'lastBeep' in function main()| main.cpp|10|Error E2451 : Undefined symbol 'curTime' in function main()| main.cpp|13|Error E2268 : Call to undefined function 'difftime' in function main()| main.cpp|15|Error E2268 : Call to undefined function '_kbhit' in function main()| – Harsh Aug 02 '12 at 13:46
  • main.cpp|21|Error E2268 : Call to undefined function 'difftime' in function main()| – Harsh Aug 02 '12 at 13:47
  • These are the errors I get when i try to run it on codeblocks – Harsh Aug 02 '12 at 13:48
  • @Harsh That looks like errors in the way codeblocks is configured (not finding header files). Can't help you there I'm afraid. – BoBTFish Aug 02 '12 at 14:17
  • I second the use of `_kbhit()`. However, `difftime()` is not available on Windows. I suggest a simple `Sleep(100)` and beeping every 10th iteration. After all, this task does not require great precision, and the user probably won't notice a 100ms delay before their input is processed. – atzz Aug 02 '12 at 14:18
  • @atzz Really? As I said I've compiled and run it, `difftime()` is in the standard? Perhaps it's not there in some versions of windows, or some compilers? – BoBTFish Aug 02 '12 at 14:31
  • Just 1 question? How can I extract the keystroke that cause the kbhit to change its value? I think I am close... – Harsh Aug 02 '12 at 14:33
  • Also I see that kbhit is terminating the program – Harsh Aug 02 '12 at 14:37
  • Once `_kbhit()` has returned `true`, there is something there to read in. In my example, I read a word into the `std::string` called `input` (which means you are back to blocking until the hit enter, so it's not a great example now I think about it.) – BoBTFish Aug 02 '12 at 14:37
  • @BoBTFish How can I prevent kbhit from terminating the whole program – Harsh Aug 02 '12 at 14:38
  • Re: `difftime` - the docs say you're right and I'm wrong, so I guess my memory failed me. :) Maybe it pertains to some ancient version of MSVC, I can't say now. Anyway, MSDN says `difftime()` is there and declared in ``. – atzz Aug 02 '12 at 14:40
  • I just need to know how can store the keystroke that caused kbhit to change value? Please I think that would be the last piece of the puzze.. – Harsh Aug 02 '12 at 14:43
  • @Harsh, I've changed it to use `_getch()` to read back the key they hit. And it's not ending the program exactly, it's just in my example there is nothing else to do afterwards. For your own program, it would maybe be in a function you call for each question or something, and then you would move on to the next question. – BoBTFish Aug 02 '12 at 14:45
  • @BoBTFish That means input=getch() would be extracting the keystroke that caused kbhit() to change its value? Right? – Harsh Aug 02 '12 at 14:48
  • Thanks Sir @BoBTFish. I think that has solved my problem for the time being...I will revert back if I ran into any else problem regarding this... :) – Harsh Aug 02 '12 at 14:52
  • @Harsh Yes. Roughly, `_kbhit()` means "a key was pressed", and `_getch()` means "get the last key that was pressed". – BoBTFish Aug 02 '12 at 14:52
-1

For windows: #include <windows.h> ... Beep(1480,200); // for example. ...

Beep() executes in separate thread in kernel (as i know), so you can do not care about multithreading - while it executes, your profram can check the input, or type new question, for example

Pavlus
  • 1,651
  • 1
  • 13
  • 24
  • http://msdn.microsoft.com/en-us/library/windows/desktop/ms679277%28v=vs.85%29.aspx Synchronous call, so you can't try to get input while beeping. – BoBTFish Aug 02 '12 at 13:19
  • Getting input from the user with e.g. `std::cin` is also blocking, which means it wont beep more than once. – Some programmer dude Aug 02 '12 at 13:27
  • I don't hear any beep, could it be possible that I am using wrong frequency? – Harsh Aug 02 '12 at 13:32
  • @Harsh - it doesn't work on modern hardware, unless you're running Windows 7. Read the *Remarks* here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms679277%28v=vs.85%29.aspx – atzz Aug 02 '12 at 14:11