-3

I've recently tried cpp, in the thing I'm making I'm trying to make it so that a variable with the value of 20 is subtracted by 1 every second, but I also need the machine to be waiting for an input from the user. I tried using for loops but they won't proceed until the input is placed or until the variable runs out. I looked at clock but they don't seem to fit my need, or maybe I just misunderstood their purpose.

Any suggestions?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • please clarify what "also need to be waiting for an input" How does that fit with the variable countdown? – bolov Apr 23 '17 at 00:21
  • 1
    Running in the background generally requires threading. I have far more experience with C than C++, but as far as I know threading in C++ is similar to C in the sense that it usually relies on system libraries (e.g., `pthread.h` on POSIX-compliant machines). As such, the operating system you are using would be a major factor in formulating a solution. All of that said, please include the code you have tried. StackOverflow is here to help with resolving problems, but those of us in the community are not here just to write code for others. – Spencer D Apr 23 '17 at 00:21
  • I am guessing you want a windows media timer. For that and for any real timer at that, you need to be developing in a winapi environment. (Assuming Windows). – Evan Carslake Apr 23 '17 at 00:26
  • @SpencerD: _"as far as I know threading in C++ is similar to C in the sense that it usually relies on system libraries"_ That hasn't been true for many years. We've had Boost.Thread for over a decade, and a fully standardised multi-threaded memory model since 2011. – Lightness Races in Orbit Apr 23 '17 at 00:26
  • 1
    You've tried a few things, please post/detail what you've tried and why it doesn't do what you need. That will help others to help you. – kabdulla Apr 23 '17 at 00:27
  • @BoundaryImposition, the more you know. As I said, I am far more familiar with C. Based on a quick google search, it looks like that changed in C++11? Regardless, thanks for the info. – Spencer D Apr 23 '17 at 00:35
  • @SpencerD: Through C++03 we used Boost as a platform-agnostic wrapper around system-specific calls. – Lightness Races in Orbit Apr 23 '17 at 01:27
  • Depending on your OS, waiting for an input with a timeout should achieve what you are looking for. If the input is given, fine. If it times out then your timer comes into effect. Alternatively, the main event loop just picks up events - whether it's a timer or user input doesn't matter. – Mike Apr 23 '17 at 05:06

1 Answers1

0

As has already been suggested in the comments, threading is one way to do this. There is a nice self-contained example here (which I've borrowed from in the code below).

In the code below an asynchronous function is launched. Details on these here. This returns a future object which will contain the result once the job has finished.

In this case the job is listening to cin (typically the terminal input) and will return when some data is entered (i.e. when enter is pressed).

In the meantime the while loop will be running which keeps a track of how much time has passed, decrements the counter, and also returns if the asynchronous job finishes. It wasn't clear from your question if this is exactly the behaviour you want but it gives you the idea. It will print out value of decremented variable, but user can enter text, and it will print that out once user presses enter.

#include <iostream>
#include <thread>
#include <future>
#include <time.h>

int main() {
    // Enable standard literals as 2s and ""s.
    using namespace std::literals;

    // Execute lambda asyncronously (waiting for user input)
    auto f = std::async(std::launch::async, [] {
        auto s = ""s;
        if (std::cin >> s) return s;
    });

    // Continue execution in main thread, run countdown and timer:
    int countdown = 20;
    int countdownPrev = 0;
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    std::chrono::steady_clock::time_point end;

    double elapsed;

    while((f.wait_for(5ms) != std::future_status::ready) && countdown >= 0) {
        end = std::chrono::steady_clock::now();
        elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
        countdown = 20 - (int) (elapsed/1000);

        if (countdown != countdownPrev) {
            std::cout << "Counter now: " << std::fixed << countdown << std::endl;
            countdownPrev = countdown;
        }
    }
    if (countdown == -1) {
        std::cout << "Countdown elapsed" << std::endl;
        return -1;
    } else {
        std::cout << "Input was: " << f.get() << std::endl;
        return 0;
    }
}

P.S. to get this to work on my compiler I have to compile it with g++ -pthread -std=c++14 file_name.cpp to correctly link the threading library and allow use of c++14 features.

Community
  • 1
  • 1
kabdulla
  • 5,199
  • 3
  • 17
  • 30