Stopwatch console application in C++
Do not miss this exclusive book on Binary Tree Problems. Get it now for free.
In this article, we have developed a stopwatch as a console application in C++ Programming Language. This involve the concept of using threads. This is a good project for SDE portfolio.
Introduction
A stopwatch is a timer application that you can stop it at any moment.
Starting from this point you can think how you can design an application that can start, stop and reset the time.
The unit base for a time is second.
1 sec = 1000 milli
1 min = 60 sec
A way of implementation
My design is using a class named Stopwatch that basically models a time by defining the variables milli,sec and min and some methods to simulate it. state variable is used to check weather the time is running or not.
To simulate a stopwatch we need to start a time and in the same time to read some characters from the keybord.
To achieve that I have used the libraries thread and chrono in which we can call the sleep_for function.
this_thread::sleep_for(chrono::milliseconds(10));
Notice that the milli loop stops at 100. Why is that ? because the sleep_for is sleeping for 10 milli seconds and multiplying with 100 gives us 1000 that represent 1 second in real time.
It is VERY important to check the state at every moment, otherwise we would not know when to take an action of the watch. This is done by checking the state at every loop condition except for the first one that is a continous loop.
while(min < 60 && state)
{
while(sec < 60 && state)
{
while(milli < 100 && state)
The program creates an object of type Stopwatch and initialize a thread for it by calling the method run. First time, the state variable is false.
The initialization of the thread is done by declaring the object w using its constructor that it receives as paramters a pointer to a function and a reference of the object that belongs to it.
Stopwatch st;
thread w(&Stopwatch::run, ref(st));
Then in parallel, inside a loop, we always listen for a keyboard input.
do
{
cin>>kb;
switch(kb)
{
case KB_s: st.start(); break;
case KB_t: st.stop(); break;
case KB_r: st.reset(); break;
}
}
while (kb != KB_ESC);
If the key s is pressed then we change the state variable to true and because we have a thread that is already running, it checks for the state to see if it is true and starts the loop, i.e. the time.
Similar, for the r and t keys, the state and time variables are changed.
#include <iostream>
#include <iomanip>
#include <chrono>
#include <thread>
#define KB_s 115
#define KB_t 116
#define KB_r 114
#define KB_ESC 27
using namespace std;
class Stopwatch
{
int milli;
int sec;
int min;
bool state;
public:
Stopwatch()
{
milli=0;
sec=0;
min=0;
state=false;
}
void run()
{
while(true)
while(min < 60 && state)
{
while(sec < 60 && state)
{
while(milli < 100 && state)
{
cout<<"\r"<<setw(2)<<setfill('0')<<min<<":"<<setw(2)<<setfill('0')<<sec<<","<<setw(2)<<setfill('0')<<milli++<<flush;
this_thread::sleep_for(chrono::milliseconds(10));
}
if(state)
milli=0, sec++;
}
if(state)
sec=0, min++;
}
}
void start()
{
state = true;
}
void stop()
{
state=false;
}
void reset()
{
milli=0;
sec=0;
min=0;
state=false;
cout<<"\r"<<setw(2)<<setfill('0')<<min<<":"<<setw(2)<<setfill('0')<<sec<<","<<setw(2)<<setfill('0')<<milli++<<flush;
}
};
int main()
{
cout<<"Press s to start counting, t to stop it and r to reset it. Esc to exit."<<endl;
char kb;
Stopwatch st;
thread w(&Stopwatch::run, ref(st));
do
{
cin>>kb;
switch(kb)
{
case KB_s: st.start(); break;
case KB_t: st.stop(); break;
case KB_r: st.reset(); break;
}
}
while (kb != KB_ESC);
return 0;
}
Run the code as:
g++ code.cpp
./a.out
Output
Press s to start counting, t to stop it and r to reset it. Esc to exit.
s
00:02,87t
s
00:06,06t
r
00:00,00s
00:02,74t
^[
terminate called without an active exception
Get the complete C++ project at GitHub.
Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.