How to use a timer in C++

Discussion in 'Mac Programming' started by sheepopo39, Dec 14, 2009.

  1. sheepopo39 macrumors 6502

    Joined:
    Sep 18, 2008
    #1
    I'm working on a simple C++ application where a user inputs two numbers, then the program counts from the smaller number to the larger number, outputting each number. I know how to do this, but I would like it so that it only counts up, once every second. I learned how to do this in Java ages ago, but I forgot how to do it, and I'm sure it's different in C++. Anyone know what to do?

    Edit: Here's the code

    Code:
    /* A simple C++ application which asks the user 
     for two numbers, then counts from the smaller number
     to the larger number */
    #include <iostream>
    using namespace std ;
    
    int main()
    {
    	// Declares two variables of type int
    	int num1 ;
    	int num2 ;
    	int lesserNumber ;
    	int greaterNumber ;
    	
    	// Asks the user for two integer numbers
    	cout << "Please enter an integer number: " ;
    	cin >> num1 ;
    	cout << "Please enter another integer number: " ;
    	cin >> num2 ;
    	
    	// Checks to see which number is the lesser one, and which one is greater
    	if ( num1 < num2 ) 
    	{
    		lesserNumber = num1 ;
    		greaterNumber = num2 ;
    	}
    		
    	else 
    	{
    		lesserNumber = num2 ;
    		greaterNumber = num1 ;
    	}
    	
    	//Outputs the numbers from lesserNumber to greaterNumber
    	for ( lesserNumber; lesserNumber <= greaterNumber ; lesserNumber++ )
    	{
    			cout << "Number: " << lesserNumber << endl ;
    	}
    }
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    http://www.manpagez.com/man/3/Sleep/

    sleep will sleep for at least the number of seconds you say. This means that you shouldn't depend on it to be EXACTLY a second, but at least a second.

    -Lee
     
  3. Gyro1 macrumors newbie

    Joined:
    Dec 11, 2009
    #3
    Timers

    This uses a function that increments a number by 1 every second until max seconds has been reached. Since the while loop is constantly polling time() for a value, its not as efficient as spinning off your own thread, but it gets the job done.

    Code:
    
    #include <ctime>
    #define MAX_COUNT 60
    
    time_t Sys_GetTime()
    {
         return time(NULL);
    }
    
    void TheFinalCountdown(int max)
    {
         time_t lastTime = 0, currentTime = 0;
         int count = 0;
    
      lastTime = Sys_GetTime();
    
      while (count < max)
      {
           currentTime = Sys_GetTime();
    
           if (currentTime - lastTime >= 1)  {
                  count++;
                  lastTime = Sys_GetTime();
                  printf("Value: %d\n", count);
           } 
      }
    }
    
    int main ()
    {
      TheFinalCountdown();
      return 0;
    }
    
    
     
  4. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #4
    Of course, this also has multiple *time* problems relative to simply using sleep(). This will *average* one second intervals with max being very large. Unfortunately, the first time period will also average .5 seconds. You're better off just using sleep(), as it will only be off by a few milliseconds, but it will be a few milliseconds over 1000ms. If those milliseconds count, then this is a problem. For what the OP is requesting, this is the best and easiest approach.
     
  5. sheepopo39 thread starter macrumors 6502

    Joined:
    Sep 18, 2008
    #5
    Thanks everyone for your input. I ended up using lee1210's solution by using "sleep(value)" however, I got that all working but I am now faced with another problem

    Code:
    /* A simple C++ application which asks the user 
     for two numbers, then counts from the smaller number
     to the larger number */
    #include <iostream>
    #include <unistd.h>
    
    using namespace std ;
    
    int main()
    {
    	// Declares two variables of type int
    	int num1 ;
    	int num2 ;
    	int lesserNumber ;
    	int greaterNumber ;
    	int numberOfCounts = 1 ;
    	
    	// Asks the user for two integer numbers
    	cout << "Please enter an integer number: " ;
    	cin >> num1 ;
    	cout << "Please enter another integer number: " ;
    	cin >> num2 ;
    	
    	// Checks to see which number is the lesser one, and which one is greater
    	if ( num1 < num2 ) 
    	{
    		lesserNumber = num1 ;
    		greaterNumber = num2 ;
    	}
    		
    	else 
    	{
    		lesserNumber = num2 ;
    		greaterNumber = num1 ;
    	}
    	
    	//Outputs the numbers from lesserNumber to greaterNumber
    	for ( lesserNumber; lesserNumber <= greaterNumber ; lesserNumber++ )
    	{
    		
    		// Checks if the number of counts is equal to 1
    		if ( numberOfCounts == 1 )
    		{
    			cout << "First number: " << lesserNumber << endl ;
    		}
    		
    		else if ( numberOfCounts < greaterNumber - lesserNumber )
    		{
    			cout << "Number: " << lesserNumber << endl ;
    		}
    		
    		else if ( numberOfCounts == greaterNumber - lesserNumber )
    		{
    			cout << "Final number: " << lesserNumber << endl ;
    		}
    		
    		numberOfCounts++ ;
    		sleep(1) ;
    	}
    	
    	return 0 ;
    }
    Say you enter 1 and 10, then the output is

    Code:
    First number: 1
    Number: 2
    Number: 3
    Number: 4
    Final number: 5
    
    I'm not sure what's causing this.
     
  6. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #6
    You're incrementing lesserNumber AND numberOfCounts every time through the loop. This screws up your comparisons.
     
  7. sheepopo39 thread starter macrumors 6502

    Joined:
    Sep 18, 2008
    #7
    Thanks, but how exactly does it screw it up? Any idea on what I could do to change it?
     
  8. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #8
    Don't increment lesserNumber. You're already counting with numberOfCounts. Start numberOfCounts at zero and add it to lesserNumber to get the current number.

    The problem is this: numberOfCounts == greaterNumber - lesserNumber

    With a little algebra, you get this:

    numberOfCounts + lesserNumber == greaterNumber

    If you increment both, you get closer to greaterNumber by two every time through the loop, so you get there faster than you expect.
     
  9. sheepopo39 thread starter macrumors 6502

    Joined:
    Sep 18, 2008
    #9
    Ok, I'll try that, thanks, but why can't you do more than one incrementation in a loop.
     
  10. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #10
    Do the above to see an important detail of why it doesn't work.
     
  11. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #11
    You can increment as many as you want. Your math is wrong. That's all.
     
  12. sheepopo39 thread starter macrumors 6502

    Joined:
    Sep 18, 2008
    #12
    Alright, I still don't get it.

    But thanks anyways.

    John.

    Edit: Sorry for being a pain

    But, shouldn't it only apply to numberOfCounts == greaterNumber - lesserNumber, why would they switch?
     
  13. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #13
    You can increment multiple things, but your logic is wrong. The reason it is wrong is because you are wanting to test numberOfCounts to a quantity (greaterNumber - lesserNumber). This quantity (...) is assumed to never change, it is assumed that only numberOfCounts will change.
    HOWEVER you are changing lesserNumber on every pass through the loop.

    Hence what happens is that your loop runs for the full number of times, but you have only programmed it to output a number for 3 scenarios, neglecting the scenario when (numberOfCounts > greaterNumber - lesserNumber)

    Though I really don't like your personal "style" here, I'd suggest doing one of the two changes to the loop I post here. Both require a new int, to stabilize the (...) quantity.

    Code:
    int differenceNumber = greaterNumber - lesserNumber;
    for ( lesserNumber; lesserNumber <= greaterNumber ; lesserNumber++ )
    	{
    		
    		// Checks if the number of counts is equal to 1
    		if ( numberOfCounts == 1 )
    		{
    			cout << "First number: " << lesserNumber << endl ;
    		}
    		
    		else if ( numberOfCounts < differenceNumber )
    		{
    			cout << "Number: " << lesserNumber << endl ;
    		}
    		
    		else if ( numberOfCounts == differenceNumber )
    		{
    			cout << "Final number: " << lesserNumber << endl ;
    		}
    		
    		numberOfCounts++ ;
    		sleep(1) ;
    	}
    
    OR

    Code:
    int originalLesserNumber = lesserNumber;
    for ( lesserNumber; lesserNumber <= greaterNumber ; lesserNumber++ )
    	{
    		
    		// Checks if the number of counts is equal to 1
    		if ( numberOfCounts == 1 )
    		{
    			cout << "First number: " << lesserNumber << endl ;
    		}
    		
    		else if ( numberOfCounts < greaterNumber - originalLesserNumber )
    		{
    			cout << "Number: " << lesserNumber << endl ;
    		}
    		
    		else if ( numberOfCounts == greaterNumber - originalLesserNumber )
    		{
    			cout << "Final number: " << lesserNumber << endl ;
    		}
    		
    		numberOfCounts++ ;
    		sleep(1) ;
    	}
    

    -------------------------------------
    His loop is NOT terminating faster than it should, it is simply not displaying any output on the last passes.
     
  14. sheepopo39 thread starter macrumors 6502

    Joined:
    Sep 18, 2008
    #14
    Ok, I think I get it, but I don't know why it does half of it or whatever. So, you simply cannot have operators when you do a "==" comparison.

    So

    Code:
    a == b - c
    Wouldn't work

    Instead, one of the ways could be

    Code:
    int d = b - c
    a == d

    EDIT: Also I did the changes that you suggested, but however, it does count up past 5, but when it reaches nine it says "Final Number: 9" instead of 10, and when it reaches 10 it says "ERROR: 10"

    EDIT 2: Nevermind, I fixed it, simply changed the code to read this

    Code:
    else if ( numberOfCounts <= differenceNumber )
    	{
    		cout << "Number: " << lesserNumber << endl ;
    	}
    		
    	else if ( numberOfCounts > differenceNumber )
    	{
    		cout << "Final number: " << lesserNumber << endl ;
    	}
     
  15. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #15
    A better loop using only variables you have initialized would be...
    Code:
    // using numberOfCounts to do the actual loop counting ;)
    for (numberOfCounts = lesserNumber; numberOfCounts <= greaterNumber; numberOfCounts++ ) {
    		
    		if ( numberOfCounts == lesserNumber ) {
    			cout << "First number: " << numberOfCounts << endl;
    		} else if ( numberOfCounts == greaterNumber ){
    			cout << "Final number: " << numberOfCounts << endl;
    		} else {
    			cout << "Number: " << numberOfCounts << endl;
    		}
    
    		sleep(1);
    	}
    
    Or even better because it separates the logic required output from the always output.
    Code:
    // using numberOfCounts to do the actual loop counting ;)
    for (numberOfCounts = lesserNumber; numberOfCounts <= greaterNumber; numberOfCounts++ ) {
    		
    		if ( numberOfCounts == lesserNumber ) {
    			cout << "First number: ";
    		} else if ( numberOfCounts == greaterNumber ){
    			cout << "Final number: ";
    		} else {
    			cout << "Number: ";
    		}
                    cout << numberOfCounts <<endl;
    		sleep(1);
    	}
    
     
  16. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #16
    You absolutely can test a == b - c, in fact you did test that.
    Your problem is that a and c were both going up. Your scenarios were setup in such a way that they would do the right thing IF and ONLY IF b-c was a static quantity.

    Your second code fragment will work because it saves a snapshot of b - c and stores it in d. Since you never again modify d, the loop behaves how you want it to.
     
  17. sheepopo39 thread starter macrumors 6502

    Joined:
    Sep 18, 2008
    #17
    Ooooooooh, ok, I completely understand it now, thanks a lot for your help everyone.

    And yes, I know I don't have the cleanest syntax ;)

    Edit: This sleep() command has given me so many ideas
     
  18. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #18
    Think how many ideas you'd have if you were working in Objective-C and had access to NSTimer. You may be able to use NSTimer in C++ I guess.
     
  19. Sander macrumors 6502

    Joined:
    Apr 24, 2008
    #19
    Happens for me too. Sometimes I just can't find a solution, but after a sleep() with a fresh mind, the solution just pops up.

    :)
     
  20. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #20
    I am well aware of this. Hence my change to his code to spit out an error message.

    Also, I try not to lay out complete solutions to problems that look like homework assignments. I've seen way too many people successfully acquiring CS degrees who can't program worth a flip. It does no one any good to pass someone who can't figure this stuff out, least of all the student.

    Also, if you're going to complain about style, you could simply say that the entire process of comparing the numbers is completely irrelevant. The first printout should go before the loop, and the last printout should go after the loop. The only comparison that needs to be made is the loop itself (and ensuring the two numbers are different). However, we're not trying to rewrite this person's code for them.
     
  21. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #21
    Sure, so the best way to have him learn is to say that something is happening when it is not happening so he is looking at the wrong part of logic? As far as you know it is not for homework. He didn't say it was. So by not helping as much as you can with things like style and pointing out the actual error you are either hindering or possibly calling him a liar.

    If you mean to put the First number: num and Last number: num outside of the for loop, then I don't think that is stylistically better.
    #1. I believe the prefix part of the output (first num, last num, num) is integral to the logic and nature of the loop itself. Thus it is easier to read if it is all inside a for or while loop.

    #2. Without even more logic you run the risk of printing incorrect data, namely if lesserNumber == greaterNumber you would print both all the time since they are outside of the loop (assuming the loop doesn't run even once, if it did run once it would likely print the same number a third time).


    As far as style goes, I was mostly commenting on the use of essentially two counters in a loop, one for testing logic and one for printing output. And incrementing a data input he captured from the user, vs copying it and keeping the original around for later use like printing out or comparing.
    That and the WHOLE lot of white space.
     

Share This Page