how to make it stop

Pages: 12
May 12, 2020 at 12:05pm
So I've got this code here, it's a stopwatch. And the only problem with it is that it doesn't stop. I would like it to stop counting time when I, for example, press the "p" button. Could you help me?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 #include <iomanip> 
#include <iostream> 
#include <stdlib.h> 
#include <unistd.h> 
using namespace std; 
   
int hours = 0; 
int minutes = 0; 
int seconds = 0; 
   
void displayClock() 
{ 
   
    system("clear"); 
  
    cout << setfill(' ') << setw(55) << "         STOPER         \n"; 
    cout << setfill(' ') << setw(55) << " --------------------------\n"; 
    cout << setfill(' ') << setw(29); 
    cout << "| " << setfill('0') << setw(2) << hours << " hrs | "; 
    cout << setfill('0') << setw(2) << minutes << " min | "; 
    cout << setfill('0') << setw(2) << seconds << " sec |" << endl; 
    cout << setfill(' ') << setw(55) << " --------------------------\n"; 
} 
  
void timer() 
{ 

    while (true) { 
          
        displayClock(); 
        sleep(1); 
   
        seconds++; 
  
        if (seconds == 60) { 
          
            
            minutes++; 
  
             
            if (minutes == 60) { 
          
             
                hours++; 
                minutes = 0; 
            } 
            seconds = 0; 
        } 
    } 
} 
  
 
int main() 
{ 
   
    timer(); 
    return 0;
}
May 12, 2020 at 12:12pm
Hm... I’d say you can either use threads or the select function to solve that.

Threads make it possible to have your program do several things at once, so you could use it to have one thread constantly waiting for input, that input being a 'q', and a second thread constantly sending the timer output to that screen.

The select() function tests for a specified amount of time whether or not a specified file descriptor has some info to read. Using this you could instead have a single infinite loop that displays the clock, tests for input for some amount of time, and then displays the clock again.
May 12, 2020 at 12:21pm
I think it's too advanced for me but thank you so much for help!
May 12, 2020 at 12:24pm
Alright.... are you sure? I can show you and select is just one function..
May 12, 2020 at 12:32pm
You can try but I need as simplest explenation as possible. I'm not very good with c++ and my professor wants me to be an expert or he gives a bad grade...
I'm trying my best but it's still too little.
May 12, 2020 at 12:59pm
:/ ahh oof. Ok. Ok, so I think I’ll take the thread route, because it’ll be easier for this.

As defined by this site:
A thread of execution is a sequence of instructions that can be executed concurrently with other such sequences in multithreading environments, while sharing a same address space.



Most of that is irrelevant jargon. Let’s just focus on two things:
executed concurrently
and
sharing a same address space.
.

The first, basically, "done at the same time", and the second just means in our case that they can share variables and data.


That being said this means I could



Ok that went a bit far. Threads means executing at the same time. That’s all. Sry lol. Ok. Anyways.


To use threads, we must include the thread header
#include <thread>
Then to make a thread, we pass a function to the thread constructor. (If you don’t know what that is, don’t worry, it’s not entirely relevant to this atm.)
std::thread(function_name);
now you have a thread running that function. So to use your program as an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <thread>
#include <iomanip> 
#include <iostream> 
#include <stdlib.h> 
#include <unistd.h> 
using namespace std; 
   
int hours = 0; 
int minutes = 0; 
int seconds = 0; 
   
void displayClock() 
{ 
   
    system("clear"); 
  
    cout << setfill(' ') << setw(55) << "         STOPER         \n"; 
    cout << setfill(' ') << setw(55) << " --------------------------\n"; 
    cout << setfill(' ') << setw(29); 
    cout << "| " << setfill('0') << setw(2) << hours << " hrs | "; 
    cout << setfill('0') << setw(2) << minutes << " min | "; 
    cout << setfill('0') << setw(2) << seconds << " sec |" << endl; 
    cout << setfill(' ') << setw(55) << " --------------------------\n"; 
} 
  
void timer() 
{ 

    while (true) { 
          
        displayClock(); 
        sleep(1); 
   
        seconds++; 
  
        if (seconds == 60) { 
          
            
            minutes++; 
  
             
            if (minutes == 60) { 
          
             
                hours++; 
                minutes = 0; 
            } 
            seconds = 0; 
        } 
    } 
} 
  
 
int main() 
{ 
   
    std::thread(timer);
    while(true); // I’m doing nothing in this thread, but stuff is still happening! :D
    return 0;
}


Now how is this helpful? Well, this means that you can do two things at once without them interrupting or blocking each other. This means you can check for input and display output at the same time!

Your turn!

Steps:
1
2
1) make thread running func
2) cin a character. Is it q? Exit!



Ask as many questions as you need. 🤷‍♂️
May 12, 2020 at 1:02pm
Oh also, here’s this site’s example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// thread example
#include <iostream>       // std::cout
#include <thread>         // std::thread
 
void foo() 
{
  // do stuff...
}

void bar(int x)
{
  // do stuff...
}

int main() 
{
  std::thread first (foo);     // spawn new thread that calls foo()
  std::thread second (bar,0);  // spawn new thread that calls bar(0)

  std::cout << "main, foo and bar now execute concurrently...\n";

  // synchronize threads:
  first.join();                // pauses until first finishes
  second.join();               // pauses until second finishes

  std::cout << "foo and bar completed.\n";

  return 0;
}
May 12, 2020 at 1:22pm
Ok, so my first question is why I have this error when I try to run a code with thread:

#error This file requires compiler and library support for the \
ISO C++ 2011 standard. This support is currently experimental, and must be \
enabled with the -std=c++11 or -std=gnu++11 compiler options.

And a second one, where I should put the first thread? maybe the place choosen by me isn't right, will putting just std::thread is enough to stop the program? or how to include this "q", what does that even mean?
ok, more than one question...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <thread>
#include <iomanip> 
#include <iostream> 
#include <stdlib.h> 
#include <unistd.h> 
using namespace std; 
   
int hours = 0; 
int minutes = 0; 
int seconds = 0; 
{   
void displayClock()
std::thread(displayClock);
}
{ 
   
    system("clear"); 
  
    cout << setfill(' ') << setw(55) << "         STOPER         \n"; 
    cout << setfill(' ') << setw(55) << " --------------------------\n"; 
    cout << setfill(' ') << setw(29); 
    cout << "| " << setfill('0') << setw(2) << hours << " hrs | "; 
    cout << setfill('0') << setw(2) << minutes << " min | "; 
    cout << setfill('0') << setw(2) << seconds << " sec |" << endl; 
    cout << setfill(' ') << setw(55) << " --------------------------\n"; 
} 

void timer() 
{ 

    while (true) { 
          
        displayClock(); 
        sleep(1); 
   
        seconds++; 
  
        if (seconds == 60) { 
          
            
            minutes++; 
  
             
            if (minutes == 60) { 
          
             
                hours++; 
                minutes = 0; 
            } 
            seconds = 0; 
        } 
    } 
} 
  
 
int main() 
{ 
   
    std::thread(timer);
    while(true); // I’m doing nothing in this thread, but stuff is still happening! :D
    return 0;
}


I'm so sorry for being terrible at this
May 12, 2020 at 2:34pm
....oh. Dam. Um. So that means that your compiler probably doesn’t support threads because it’s a c++11 feature. This is strange. What compiler are you using? Can you update it...?


std::thread(timer) makes a thread running the timer function. It does not stop the program. That example program just runs forever. Sorry about the q, I was just talking about the order in which an example program could go. Like

1
2
3
4
5
char c;
std::thread(timer); // make thread
cin >> c; // cin a character
if(c == 'q') // is the character a 'q'?
  exit(0); // exit! 
Last edited on May 12, 2020 at 2:34pm
May 12, 2020 at 3:07pm
I'm using dev c++, don't know if it can be updated.
okay, so what does stop the program?
Thank you for your patient, I'm literally crying my eyes out for four days trying to make it work and it doesn't.
May 12, 2020 at 3:18pm
The program stops because the main thread (literally the main function in this case) either returns or exits. Either way that signals the end of the entire process, so all threads are destroyed.
Here’s a little example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <chrono>
#include <thread>
#include <iostream>
using std::this_thread::sleep_for;
using namespace std;
using namespace std::chrono;


void func() {
  sleep_for(seconds(10)); // wait for 10 seconds.
  cout << "I’m finished!" << flush;
}

int main() {
  std::thread(func);
  cout << "never!!" << flush;
  return 0;
}


The words "I’m finished!" will never appear on the screen because the main function returns before the 10 seconds of waiting are up.
May 12, 2020 at 3:21pm
May 12, 2020 at 10:53pm
I'm using dev c++, don't know if it can be updated.

It can't be *updated. You should consider getting a newer IDE able to work with the newer language standards. Visual Studio or Code::Blocks. Dev-C++ is no longer actively supported.

MSVC has a free version available, and C::B is also free.

https://www.learncpp.com/cpp-tutorial/installing-an-integrated-development-environment-ide/

*the compiler Dev-C++ uses could be updated, but it would be a lot of work. Probably more work than just getting a newer IDE.
May 14, 2020 at 6:47pm
Okey, so I gave up with trying to make it stop, but I saw that it doesn't count time properly, it's slower. I was trying to fix it but I failed. Could someone modify this code to make it right? :( (I think the problem starts after void timer)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iomanip>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <ctime>
#include <cstdlib>

using namespace std;
 
int hours = 0;
int minutes = 0;
int seconds = 0;
 
void displayClock()
{
   
    void clear_screen();
    std::system("cls");
 
 
   
    cout << setfill( ' ' ) << setw( 55 ) << "         STOPER         \n";
    cout << setfill( ' ' ) << setw( 55 ) << " --------------------------\n";
    cout << setfill( ' ' ) << setw( 29 );
    cout << "| " << setfill( '0' ) << setw( 2 ) << hours << " hrs | ";
    cout << setfill( '0' ) << setw( 2 ) << minutes << " min | ";
    cout << setfill( '0' ) << setw( 2 ) << seconds << " sec |" << endl;
    cout << setfill( ' ' ) << setw( 55 ) << " --------------------------\n";
}
 
void timer()
{
   
  clock_t startTime = clock();
    while( true ) {
    sleep (1);
    clock_t secElapsed = (clock() - startTime) / CLOCKS_PER_SEC;
    cout << secElapsed;
    time_t sekundy = time( 0 );
      
		displayClock();     
        seconds++;
      
     
        if( seconds == 60 ) {
         
         
            minutes++;
         
         
            if( minutes == 60 ) {
             
             
                hours++;
                minutes = 0;
            }
            seconds = 0;
        }
    }
}
 

int main()
{


    timer();
    
    return 0;
}
May 14, 2020 at 7:25pm
It’s because your using your sleep statement to keep track instead of your calculations of the seconds. I’d suggest something more like



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <ctime>
#include <unistd.h>
#include <iostream>
#include <string>

void timer(clock_t start_time);
void display_clock(int hrs, int mins, int secs);

int main() {
  timer(clock());
}

void timer(clock_t start_time) {
  while(1) {
    sleep(1); // instead of using this to base your calls off of, just use it as a pausing point. A time of rest. No calcs should be based off it.
    clock_t time_elapsed = clock() - start_time;
    int hrs, mins, secs;
    secs = /* calc the amnt of seconds elapsed using time_elapsed */;
    mins = /* calc mins using secs */;
    hrs = /* calc hrs using mins */;
    display_clock(hrs, mins, secs);
  }
}

void display_clock(int hrs, int mins, int secs) {
  // erase stuff written on this line
  std::cout << std::string('\b',300) << std::flush;
  std::cout << "hrs: " << hrs << ", mins: " << mins << ", secs: " << secs;
  std::cout << std::flush;
}
Last edited on May 14, 2020 at 7:31pm
May 14, 2020 at 7:37pm
I've done it like this and it's working
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void timer()
{
   
{
    auto startTime = std::chrono::system_clock::now();
     
    while (true) {
        displayClock();
        sleep(1);
        auto currentTime = std::chrono::system_clock::now();
        seconds = std::chrono::duration<double>(currentTime - startTime).count();
        hours = seconds / 3600;
        seconds %= 3600;
        minutes = seconds / 60;
        seconds %= 60;
    }
}
}  


Now I've got this part of code which is responsible for stopping my program but it's not working. Why?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
bool ispause {false};
    auto tzero {chrono::system_clock::to_time_t(chrono::system_clock::now())};
    auto pause {chrono::system_clock::now()};
    char sign {};

    while( sign != 'e' )
    {
        if( !ispause )
        {
            auto time = chrono::system_clock::to_time_t(chrono::system_clock::now()) - tzero;
            system("cls");
            cout << put_time(gmtime(&time),"%H %M %S");
            this_thread::sleep_for(chrono::seconds(1));
        }
        if( _kbhit() ) sign = _getch();
        if( sign == 'p' )
        {
            pause = chrono::system_clock::now(); ispause = true; sign = ' ';
        }
        if( sign == 'r' )
        {
            tzero += (chrono::system_clock::to_time_t(chrono::system_clock::now())-chrono::system_clock::to_time_t(pause)); sign = ' ';
            ispause = false;
        }


Should I add something to it? Where to place it?
May 14, 2020 at 7:52pm
How is it not working?
May 14, 2020 at 8:27pm
I have this errors:

main.cpp:63:13: error: ‘this_thread’ has not been declared
this_thread::sleep_for(chrono::seconds(1));
^~~~~~~~~~~
main.cpp:65:20: error: ‘_kbhit’ was not declared in this scope
if( _kbhit() ) sign = _getch();
May 14, 2020 at 8:32pm
this_thread::sleep_for(chrono::seconds(1));

What if you put:
std::this_thread::sleep_for(chrono::seconds(1));
May 14, 2020 at 8:43pm
still the same, I'll put all my code, maybe the problem is somewhere else.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iomanip>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <ctime>
#include <cstdlib>
#include <chrono>

using namespace std;

int hours = 0;
int minutes = 0;
int seconds = 0;

void displayClock()
{

    void clear_screen();
    std::system("cls");

    cout << setfill( ' ' ) << setw( 55 ) << "         STOPER         \n";
    cout << setfill( ' ' ) << setw( 55 ) << " --------------------------\n";
    cout << setfill( ' ' ) << setw( 29 );
    cout << "| " << setfill( '0' ) << setw( 2 ) << hours << " hrs | ";
    cout << setfill( '0' ) << setw( 2 ) << minutes << " min | ";
    cout << setfill( '0' ) << setw( 2 ) << seconds << " sec |" << endl;
    cout << setfill( ' ' ) << setw( 55 ) << " --------------------------\n";
}

void timer()
{

{
    auto startTime = std::chrono::system_clock::now();

    while (true) {
        displayClock();
        sleep(1);
        auto currentTime = std::chrono::system_clock::now();
        seconds = std::chrono::duration<double>(currentTime - startTime).count();
        hours = seconds / 3600;
        seconds %= 3600;
        minutes = seconds / 60;
        seconds %= 60;
    }
}
}     

int main()
{
bool ispause {false};
    auto tzero {chrono::system_clock::to_time_t(chrono::system_clock::now())};
    auto pause {chrono::system_clock::now()};
    char sign {};

    while( sign != 'e' )
    {
        if( !ispause )
        {
            auto time = chrono::system_clock::to_time_t(chrono::system_clock::now()) - tzero;
            system("cls");
            cout << put_time(gmtime(&time),"%H %M %S");
            std::this_thread::sleep_for(chrono::seconds(1));
        }
        if( _kbhit() ) sign = _getch();
        if( sign == 'p' )
        {
            pause = chrono::system_clock::now(); ispause = true; sign = ' ';
        }
        if( sign == 'r' )
        {
            tzero += (chrono::system_clock::to_time_t(chrono::system_clock::now())-chrono::system_clock::to_time_t(pause)); sign = ' ';
            ispause = false;
        }
    }
}

    timer();

    return 0;
}
Pages: 12