Countdown timer

ben1996123 0 Tallied Votes 336 Views Share

Input the minutes, then the seconds, and it will do the rest. Pretty simple but I just thought I'd post it. Made as a quick test for my game.

#include <iostream>
#include <windows.h>
#include <cstdlib>
using namespace std;
int main(){
    int minutes;
    int seconds;
    cin >> minutes >> seconds;
    seconds = (minutes*60)+seconds;
    cout << endl;
    while(seconds>0){
        if(seconds%60<10){
            cout << seconds/60 << ":0" << seconds%60 << endl;
        }
        else{
            cout << seconds/60 << ":" << seconds%60 << endl;
        }
        Sleep(1000);
        seconds--;
    }
}

Dani AI

Generated

Nice, simple starter from — and good follow-ups from (input), (zero-padding), (single-line \r) and / (timing accuracy). The gaps left open were: robust input parsing, avoiding Sleep-driven drift, and a portable, single-line display. Below is a compact C++11+ example that addresses those points (reads a line and validates it, uses a monotonic clock + sleep_until to avoid cumulative drift, and updates the console in-place).

#include <iostream>
#include <string>
#include <sstream>
#include <chrono>
#include <thread>
#include <cstdio>

int main() {
    int minutes = 0, seconds = 0;
    std::string line;
    while (true) {
        std::cout << "Enter minutes and seconds (mm ss): ";
        if (!std::getline(std::cin, line)) return 0;
        std::istringstream iss(line);
        if (iss >> minutes >> seconds && minutes >= 0 && seconds >= 0) break;
        std::cout << "Invalid input; enter two non-negative integers.\n";
    }

    long long total = static_cast<long long>(minutes) * 60 + seconds;
    auto next = std::chrono::steady_clock::now();

    while (total >= 0) {
        int m = static_cast<int>(total / 60);
        int s = static_cast<int>(total % 60);
        std::printf("\r%02d:%02d", m, s);
        std::fflush(stdout);
        if (total == 0) break;
        next += std::chrono::seconds(1);
        std::this_thread::sleep_until(next);
        --total;
    }

    std::printf("\nTime's up.\n");
    return 0;
}

Notes and troubleshooting:

  • steady_clock is monotonic (so it won't jump if the system clock changes) and sleep_until keeps ticks aligned, preventing the drift you get from naive 1-second sleeps. Still, the OS scheduler can delay wakeups under heavy load; for sub-ms accuracy use platform timers or integrate timing into your game loop (use frame delta time).
  • %02d with \r keeps the countdown on one line; some terminals behave differently — on Windows console you can use the console cursor API if \r doesn’t overwrite the line.
  • The input loop prevents non-numeric input from breaking the program and lets you reject negatives. For very long timers use a 64-bit type for total.

This combines the formatting and single-line display ideas from and with the timing robustness that / suggested, in a portable (non-Windows-only) way.

Taywin 312 Posting Virtuoso

But it will break if I enter "a" instead of a number... :(

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You could use setw and setfill functions to avoid that if-statement in your loop. As so:

#include <iostream>
#include <iomanip>
#include <windows.h>
#include <cstdlib>

using namespace std;
int main(){
    int minutes;
    int seconds;
    cin >> minutes >> seconds;
    seconds = (minutes*60)+seconds;
    cout << setfill('0') << endl;
    while(seconds>0){
        cout << seconds / 60 << ":" << setw(2) << seconds % 60 << endl;
        Sleep(1000);
        seconds--;
    }
}
ben1996123 0 Junior Poster in Training

But it will break if I enter "a" instead of a number... :(

Well... why would you want to enter "a"?

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>Well... why would you want to enter "a"?

That's called "fool-proofing a program". Generally, when writing a program that deals with a user (either through console input, command-line input, config-file input, or a GUI), you must assume that the user has an IQ of 0, i.e., that he/she is an absolute imbecile that could be inputting anything and click on all or any buttons. That's often what beta-testing is about, have a user do all sorts of random crap and watch if the program can cope with it.

Taywin 312 Posting Virtuoso

That's called "fool-proofing a program". Generally, when writing a program that deals with a user (either through console input, command-line input, config-file input, or a GUI), you must assume that the user has an IQ of 0, i.e., that he/she is an absolute imbecile that could be inputting anything and click on all or any buttons. That's often what beta-testing is about, have a user do all sorts of random crap and watch if the program can cope with it.

Hahaha, +1 because it is to the point. ;)

doug65536 18 Light Poster

You can't rely on Sleep to reliably sleep for one second. If you read the documentation for sleep, it will specifically say that it might (and in reality, often will) sleep for more than the specified time period. If the cpu is under load (like if there are processing intensive processes contending for processor time) Sleep will be very inaccurate.

LevyDee 2 Posting Whiz in Training

Use QueryPerformanceCounter

ratatat 0 Newbie Poster

very commendable. kudos

limaulime 0 Newbie Poster

You may want to prompt user to enter the numbers, they might get scared looking at the blank screen.

doug65536 18 Light Poster

I just realized I should clarify my earlier comments about sleep. I did not mean to imply that you shouldn't call sleep, what I failed to say was, use sleep, but use another way to get how much time actually elapsed, and adapt.

For example: At the start of the loop, get the current "time" (QueryPerformanceCounter is a good way to get it, as LevyDee mentioned). Calculate what the "time" value would be at the end of the delay. Each loop, after the sleep call, check if the next sleep should be less than a second (because the time is almost up) and use that. If you need to wait more than a second more, use a second.

PalashBansal96 0 Newbie Poster

You can use \r to do the countdown on a single line, looks better. Also have to remove the endl

#include <iostream>
#include <iomanip>
#include <windows.h>
#include <cstdlib>

using namespace std;
int main(){
    int minutes;
    int seconds;
    cin >> minutes >> seconds;
    seconds = (minutes*60)+seconds;
    cout << setfill('0') << endl;
    while(seconds>0){
        cout << '\r' << seconds / 60 << ":" << setw(2) << seconds % 60;
        Sleep(1000);
        seconds--;
    }
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.