beep sound till any input - c++

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?

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

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

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

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

Related

c++ stdout flushes stream unexpectedly

#include <iostream>
#include <thread>
using namespace std;
int main()
{
for (int i = 0; i < 10000; i++) {
cout << "Hello\n";
}
this_thread::sleep_for(chrono::milliseconds(2000));
cout << "2 seconds have passed" << endl;
return 0;
}
In my code, I didn't call any std::flush or std::endl, but the hello's are printed before the 2 seconds delay. I am expecting to print all the hello's after the 2 seconds delay, but it didn't. My code runs like this:
Hello
Hello
.
.
.
Hello
Hello
(after 2 seconds)
2 seconds have passed
[terminated]
Why is this happening?
First of all, you're writing more output than a typical file buffer will hold, so you'd almost always expect at least some of the output to show up before the sleep.
Second, you're doing a lot of separate output calls, so if cout is unit-buffered, each one is going to be flushed immediately.
Third, you're writing a new-line at the end of each item, so if cout is line-buffered, (yup) each one is going to be flushed immediately.
So, if you want a better chance of seeing at least some of the output showing up after the sleep ends, turn off unit buffering and get rid of the new-lines:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main()
{
cout << nounitbuf;
for (int i = 0; i < 1000; i++) {
cout << "Hello";
}
// display something different to make it easier for user to see
// whether all output showed up before sleep or not.
cout << "...";
this_thread::sleep_for(chrono::milliseconds(2000));
cout << "2 seconds have passed" << endl;
return 0;
}
But even with this, there's no guarantee the behavior will change. Rather the contrary, most implementations go to some pain to assure that output written to the console shows up as promptly as possible, so even when you take steps toward delaying it, it'll still probably show up before the sleep. But this might improve your chances a little bit anyway.

std::this_thread::sleep_for() freezing the program

I am making a loading type function so what I wanted to do was to halt my program for a few seconds and then resume the execution inside a loop to make it look like a loading process. Looking up on web I found that I can use std::this_thread::sleep_for() to achieve this (I am doing this on linux). The problem I am facing is that I am unable to make it work with \r or any other way to overwrite the last outputted percentage as the program freezes as soon as I do it, however it works perfectly with \n and it's all confusing to understand why it'd work with a newline sequence but not with \r.
I am posting the sample code below, can someone tell me what am I doing wrong?
#include<iostream>
#include<chrono>
#include<thread>
int main()
{
for (int i = 0; i<= 100; i++)
{
std::cout << "\r" << i;
std::this_thread::sleep_for(std::chrono::seconds(rand()%3));
}
return 0;
}
I am kinda new to this topic and after some digging I found out that I am messing with the threads. But still not sure why this behavior is happening.
This works fine on my machine (Windows 10):
#include <iostream>
#include <chrono>
#include <thread>
#include <cstdlib>
#include <ctime>
int main( )
{
std::srand( std::time( 0 ) );
for ( std::size_t i { }; i < 100; ++i )
{
std::cout << '\r' << i;
std::this_thread::sleep_for( std::chrono::seconds( std::rand( ) % 3 ) );
}
}
I suggest that you write '\r' instead of "\r" cause here you only want to print \r character and "\r" actually prints two characters (\r and \0).
Also, it's better to seed rand using srand before calling it.
However, it may not work as expected in some environments so you may need to flush the output sequence like below:
std::cout << '\r' << i << std::flush;
or like this:
std::cout << '\r' << i;
std::cout.flush( );
These are equivalent.
For more info about flush see here.

Simple timer I made stops working randomly

Before I start, here is the code:
#include <iostream>
#include <ctime>
using namespace std;
int main() {
int i = 0;
while (true) {
i++;
cout << i << endl;
clock_t time = clock() + 1000;
while (clock() != time);
}
return 0;
}
So, basically, it works, however, after a little while it just stops counting down but the program is still running. I'm new to C++ programming and I don't know how to fix this. Could somebody help me out?
EDIT: I'm not wondering how to fix my program still running, I'm wondering how to fix it not outputting numbers at one point randomly.
while (clock() != time);
If you overshoot time, which is very likely given how quickly clock() increments, you'll be stuck in that loop forever.
Use <= instead, so that any greater value of clock() will break the loop.
As an aside, busy-waiting is so 1970. You should prefer a "timed wait" of some kind that blocks until a duration has elapsed.

Cout in While loop Strange behaviour

My code look like below
int i=0;
while(i<10){
cout<<"Hello";
sleep(1);
i++
}
In Windows the code prints on each loop but in Linux it prints everything after exiting while loop . And also if I put an endl at the last of cout then it prints on each loop. Why this happening ?. Can anyone explain this behavior?.
Try to use cout.flush(); maybe the two OS has different policy in term of buffering the stdout.
For efficiency reasons, sometimes the standard streams will be implemented with a buffer. Making lots of tiny writes can be slow, so it will store up your writes until it gets a certain amount of data before writing it all out at once.
Endl forces it to write out the current buffer, so you'll see the output immediately.
#include <iostream>
using namespace std;
int main()
{
int i = 0;
while(i < 10){
cout << "Hello" << endl;
sleep(1);
++i;
}
}

Controlling output of program

I'm writing a code to output fibonacci series in C++, which is simple enough, but since I'm new to programming, I'm considering ways to control
I was wondering if there's a way to control time for when outputs come out without processing time being included (e.g. If it takes .0005 seconds to process my input and I want it to repeat the output in 1 second rather than 1.0005 seconds).
I also am wondering if there's a way to just have it output (say 1) and then have it wait for me to press enter, which will make it output the second part (2).
Also, I'd appreciate any other suggestions on how to control output.
If you're on Windows, a quick way to pause is to call system("pause"); This isn't a very professional way of doing things, however.
A way to pause with the std namespace would be something like this:
cout << "Press Enter to continue . . ." << endl;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
As for your main question... If you're just dealing with text output to the user, it's not possible for them to notice a five microsecond delay. They can notice if your interval lengths fluctuate by tens of milliseconds, however. This is why sleep(..) functions sometimes fail.
Let's take your example of wanting to output another number in the Fibonacci sequence once per second. This will work just fine:
#include <ctime>
#include <limits>
#include <iostream>
void pause() {
std::cout << "Press Enter to continue . . ." << std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
int main() {
clock_t next = clock();
int prev1, prev2, cur = 0;
for (int i = 0; i < 47; ++i) {
if (i < 2) cur = i;
else cur = prev1 + prev2;
prev2 = prev1;
prev1 = cur;
while (next > clock());
std::cout << (i+1) << ": " << cur << std::endl;
next += CLOCKS_PER_SEC;
}
pause();
return 0;
}
The next number in the sequence is computed and ready to print prior to the wait, thus the computation time will not add any delay to the timed output.
If you want your program to continue outputting at a fixed rate while your program works in the background, you'll need to look into threads. You can have your results added to a queue in one thread, while another thread checks for results to print once per second.