How to add a timer loop break command that the user can input?

Hi! Me again, I have a feeling I will be posting here frequently now, I hope it's not too cumbersome.

I am now learning to create functions and I made a simple timer function. I spent half the day actually getting the damn thing to work and the second half trying to figure out how to add a user input keyword that will stop the timer immediately if entered.

I tried using string first, like in tutorial, but it doesn't work. As in I can't figure out how to make the control structures recognise it as a word and respond to it and it alone (it always throws either various compiling errors, or what more frequent access violation errors).

Then I tried using int values (just type in 1 to stop the timer), but I just can't get it to interrupt the timer.

Then I searched windows development centre, found some function called "WaitForInputIdle", thought "HurrDurr that looks useful!"... I crashed VS...

So I just ask here. Maybe you can help?
How to make an user-entered defined keyword (e.g. stop) stop the timer in this code:
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 <iostream>
#include <windows.h>
#include <ctime>

int timer(int st) //st is the time that the user can set (hence st - set timer)
{
	using namespace std;
	int sec;
	sec = 0;
	cout << "Timer starts. Tick occurs every 5 seconds \n";
	for (sec = 0; sec <= st; sec = sec + 5) 
		{
			cout << "Tick. " << sec << " seconds have elapsed \n";
			SleepEx(5000, true);
		}
	return sec;
}

int main ()
{
	using namespace std;
	int time;
	cout << "Enter how many seconds do you want (increments of 5) \n";
	cin >> time;
	timer(time);
	cout << "Timer has elapsed.";
	//cout << "Enter new value";
	//Need to turn into a loop that repeats the main function upon timeout. I will do it later.
	return 0;
}
?
I cleaned up the code a little to remove some of the embarrassing stuff I have been trying in vain.

The increment is there because I still am not entirely sure how the "for"
thing incrementation actually works so I am trying different things with it.
And changing 1 to 5 in increment is "different thing", no?

Timer returns seconds because I wanted to use it later when I figure out how to implement whatever value the function returns.
Last edited on
Something like this?
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
#include <iostream>
#include <chrono>
#include <thread>
#include <future>

std::string async_input()
{
    std::string temp;
    std::cin >> temp;
    return temp;
}

void timer()
{
    using std::chrono::steady_clock;
    using std::chrono::seconds;
    using std::chrono::milliseconds;
    steady_clock::time_point schedule = steady_clock::now() + seconds(5);
    std::cout << "Timer will tick every 5 seconds" << std::endl;
    while (true) {
        auto inp = std::async(std::launch::async,async_input);
        while (inp.wait_for(seconds(0)) != std::future_status::ready) {
            if (steady_clock::now() >= schedule) {
                std::cout << "tick" << std::endl;
                schedule += seconds(5);
            }
            std::this_thread::sleep_for(milliseconds(100));
        }
        if (inp.get() == "stop")
            break;
    }
}

int main()
{
    std::thread m(timer);
    m.join();
}

Note: ticks can occure when you are in the middle of typing. It won't break anything, but output will look messy.
Last edited on
Hmm, I dunno... It underlines almost every line with some kind of error. Starting with failing to #include all those strange libraries/headers like "chrono" or "future".

Maybe this kind of feature is way above my level for now. I mean I don't understand a thing in your code. But VS2010 also doesn't compile your code.
Last edited on
VS2010 doesn't compile your code.
Because it is C++11.
Before that standard C++ didn't support concurrency, so it wasn't possible to create treaded program without some non-standard libraries.
I suggest to move on up-to-date compilers. Either MSVS 2012 or other: gcc, clang...
Last edited on
Ok then, I will upgrade, but this is still way above my level, since I don't understand the code at all. I am using the Open Course "Introduction to C++" from MIT, which supposedly is C++11 (at least that's what it says). It seems well-structured but I am not even past the 3rd lecture notes.

I thought making a function like that would be entry-level. Hmm, apparently not.
These are useful links for you:
http://en.cppreference.com/w/
http://www.cplusplus.com/reference/
Reference, use it when you need to know what some standard function is, or to search standard libraries to something which will help you.

http://www.cplusplus.com/doc/tutorial/
http://www.learncpp.com/
Entry-level tutorials. Probably you do not need them as you have book.
I am reading this, all of these links I already know. Thing is: the tutorial here is not really a tutorial, it's more of a "How to", so I can use it while building a program, but it didn't help understand your code. Yet.

References on this website I personally do not find all that useful because search is not particularly helpful (it always returns a ton of forum posts) and until I know what each header means, I can't navigate it properly, so again: not entry level.

Whatever the case the reason I am getting lost is because of all the
steady_clock::time_point schedule
std::async(std::launch::async,async_input)

and various new input types like auto, which are clearly not entry-level. It's a problem for me because everyone says "Read the book, but modify what it says, use methods to make your own program", but it's very hard to figure out what I am and am not capable of doing at any point.

It takes someone like you to actually show that I have tried to jump over my head. So thank you, though I doubt I am using a very effective method for determining what I can write. I will keep your code for reference once I get to that level and will try to recreate this program. Thanks again.
Ok steady_clock is one of classes which should replace c-like time() function. It has a member type time_point which defines, well, point of time compatible with steady_clock.
std::async() will launch function asynchronically and return result in future (as opposed of thread() which cannot return anything)
http://en.cppreference.com/w/cpp/chrono/time_point
http://en.cppreference.com/w/cpp/thread/async
Look at the examples.

auto is a very useful keyword in C++11. It basically deduces type depending on context. So auto x = 1 is identical to int x = 1, auto y = 1.0f equals to float x = 1.0f.
In my case I could write std::future<int> instead of auto. BTW, info on std::future: http://en.cppreference.com/w/cpp/thread/future
It would be most useful when dealing with iterators (auto instead of std::map<std::string, std::vector<std::string>>::iterator) if not for new range-based for loop.

And please note that it is fastly created code, I didn't put much thought into. It might be good for reference, but there is probably more efficient and clear ways to do so.
Last edited on
Thanks a lot for all the info!
Ok I now built your code using VS2012 and guess what? It gives the SAME errors I got when trying to use string types or getline():

1
2
3
4
5
6
7
8
9
Error	1 - line 9	error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)	

Error	2 - line 29 error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::basic_string<_Elem,_Traits,_Alloc>' (or there is no acceptable conversion)

Error3 - line 9	IntelliSense: no operator ">>" matches these operands
            operand types are: std::istream >> std::string

Error4 - line 29	IntelliSense: no operator "==" matches these operands
            operand types are: std::basic_string<char, std::char_traits<char>, std::allocator<char>> == const char [5]


I got the same errors when trying to "if" a variable to typed set of characters.
Last edited on
Add #include <string>
I accidently removed it when posting code. Sorry about that.
Also make sure that VS is in C++11 mode. It probably in it by default but it is better to make sure.
Last edited on
It is in C++11, since it asked me to update my learning project from VS2010 when I first opened it.

Sigh... Now it can't open afxres.h because it apparently can't find it. Is this because I have VS Express?
Yes, it is because of Express edition. In most cases you can safely replace it with "windows.h" (or delete it, I don't see wy you need it)
Alrighty then, works now! Thanks for walking me though this, I can't imagine how annoying it was for ye. I will try to make more simple stuff until I learn more from now on.
Topic archived. No new replies allowed.