std::this_thread::sleep_for() freezing the program - c++

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.

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.

checking for spaces with c++

So I've looked around the site for someone having a similar issue but nothing has come up and it's really been perplexing me.
#include <iostream>
#include <string>
using namespace std;
string reverse(string s)
{
int start = 0;
for(int i = 0; i < s.length(); i++)
{
if(s[i]==' '){
string new_word = s.substr(start,i);
cout << new_word << endl;
start = i+1;
}
}
return "hi";
}
int main(){
cout << reverse("Hey there my name is am");
return 0;
}
When I run the tidbit of code above this is what I get as an output.
Hey
there my
my name is
name is am
is am
hi
as you can see the if condition doesn't seem to break on every space. I have also tried isspace(s[i]) and that produced the same result as above. I cannot for the life of me figure out why the if condition is getting skipped on certain white spaces and not others. Has anyone run into a similar issue?
Take a look at the reference of string::substr. It clearly states that len takes the number of characters to include in the substring. In your code you are passing the index of ' ' which is simply wrong because it does not correspond to len. Instead of using s.substr(start,i), simply use s.substr(start,i - start + 1). That should fix the problem.

Why does the following program give different output in C++?

Following program prints 1 2 3 4 5 at once. That means there is no time delay in printing the output.
#include<iostream>
#include<stdio.h>
#include <thread>
using namespace std;
int main()
{
for(int i = 1; i <= 5; ++i)
{
cout << i << " ";
// Function to sleep the thread
this_thread::sleep_for(500ms);
}
return 0;
}
But this program prints
1
2
3
4
5
one by one that means I’m getting the output with 0.5 sec time delay.
#include<iostream>
#include<stdio.h>
#include <thread>
using namespace std;
int main()
{
for(int i = 1; i <= 5; ++i)
{
cout << i << "\n";
// Function to sleep thread
// for 0.5 sec
this_thread::sleep_for(500ms);
}
return 0;
}
What is literally happening in both of above programs?
Note:You can't see the difference of both the outputs in online compiler because they show the result after termination of program.
The output may be line buffered, in which case only complete lines are sent to the underlying output device.
I'm able to get the desired output, one element at a time appears with 0.5 sec of delay. Used visual studio 2015.
I suggest you to avoid online compilers.
They generally give the complete output once in a text box.
"\n" makes the output go to next line. It is newline character

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

beep sound till any input

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