Thread: I need time remaining program?

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    54

    Question I need time remaining program?

    Hi,



    im using Turbo C 3.0 IDE. I wants to make a quiz program by using number of several questions to user with 4 answers in which one is correct. Beside that, I want to add a time remaining feature that after 30 minutes , the questions will cancel and program will close by printing message "time up" and calculating answered questions average scores...
    Plz tell me how to make time remaining function on its background.Thanks

  2. #2
    Registered User
    Join Date
    Dec 2012
    Posts
    45
    I think there is no portable way to do this. The bare, portable C doesn't provide any way to have some code running while you are waiting for some user's input.
    Though, you can find out what time is it when the user ends entering data. Then you can calculate how much time elapsed since the program started to run. If it is more than 30 minutes, just reject the last answer and proceed to calculating scores.

    Code:
    #include <stdio.h>
    #include <time.h>
    
    
    int main ()
    {
        time_t start, end;
        int i, seconds;
    
    
        start = time (NULL);
    
    
        printf ("How much is 2+2? ");
        scanf ("%d", &i);
    
    
        end = time (NULL);
        seconds = end - start;
    
    
        if (seconds > 5)
            printf ("Sorry, you were too slow.\n");
        else if (i==4)
            printf ("That's correct.\n");
        else
            printf ("Wrong.\n");
    
    
        return 0;
    }

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Code:
    #include <stdio.h>
    #include <time.h>
    #include <conio.h>  //or windows.h
    
    
    int main ()
    {
        time_t start, now;
        int i, ok=0,seconds;
    
    
        start = time (NULL);
    
        gotoxy(15,12);
        printf ("How much is 2+2? ");
        fflush(stdout);
        ok=scanf ("%d", &i);
    
        now = start;
        gotoxy(10,10);
        printf("Time remaining: );
        fflush(stdout);
        while(!ok) {
           gotoxy(10,26);
           now = time(NULL);
           printf(" %d ", 5 - (now-start));
           fflush(stdout);
           gotoxy(15,12);
           //use delay(), (Sleep() in MS Windows), to give a 1/5th of a 
           //second delay or so. The timer (and there are other ways to 
           //make a timer), should show the time (at 10,10), about 3-5 times 
           //per second. Since it's in the same spot each time, it looks good.
           //then the cursor return immediately to 10,26, to get user's input.
           //and naps just a bit. 
           end = time (NULL);
           
           seconds = now - start;
           if (seconds>4)
               break;
        }
        if (seconds > 5)
            printf ("Sorry, you were too slow.\n");
        else if (i==4)
            printf ("That's correct.\n");
        else
            printf ("Wrong.\n");
    
    
        return 0;
    }
    I haven't run the above code, and I'm sure it would need some tweaking, (they usually do), but the idea:

    1) always put the cursor into one of two place places, that will remain constant: the timers location, and the spot for user's input

    2) use a sub second delay so the timer is being printed at least 3 times per second, but not more than 10 times per second.


    3) Immediately after printing the time remaining, move the cursor back to the user's input location, and do the delay again.

    This is "old school" and single threaded. Windows has new timers with better ways of doing this. I don't know about Linux and OSX, but they probably have better timers, as well.

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    As has been said, there's no portable or standard way to do what you want. If you don't mind being wedded to a particular compiler/platform, then you can probably just about do it. The only real comment I'll make on Adak's code is:

    Code:
        ok=scanf ("%d", &i);
    This'll block waiting for user input. If the scanf were inside the loop, you'd have pretty much the same thing as comocomocomo suggested.

    I think to pretend to have an asynchrounous timer you do at least need to have asynchronous I/O. That is, you need to continue counting down the timer regardless of whether the user has typed anything yet. This is once again a problem without a portable standard answer. I'm not sure what functionality Turbo C 3.0 provides - if it provides the kbhit function you can use that to notice when a key has been pressed:

    Code:
    while (seconds < limit)
    {
       if (kbhit())
       {
          c = getch();
          break; // or check the value here
       }
    
       // rest of the timing code.   
    }

    It'll work with a bit of fiddling, but it's not good and not nice. Since it's never going to be portable, I'd suggest delving into whatever platform specific mechanisms you can find to accomplish this over trying to keep it all in 1 big bad loop.
    You could create a separate thread to count down by reading time() like has been shown here. You'd have to communicate "time expired" and "all answers guessed, stop counting" between the threads, but that shouldn't be too hard.

    Or you could look into proper timers. I've no idea how this works in Windows unless you're writing a Windows GUI program that already has a concept of events (in which case you'd register a function to handle the event). In Linux I think you'd use setitimer or alarm to raise a signal. My experience with Windows is that triggering a Timer event every 1s 30 times won't give you 30 seconds -- it'll be somewhat more than that due to overheads. So you'd probably still want to check time() to figure out how much time had really elapsed.

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    54
    Thanks for ur help but it is not that function i wanted. I will try much.

  6. #6
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Rather than use conio.h, you could use curses. This will make it implicitly portable and easier to debug. Also there is no need to deal with events, threads, etc. You must manually process your input, though. On Linux you can link with ncurses and on other operating systems, link with pdcurses. To implement a simple input routine with a timeout, here is an example

    Code:
    #include <curses.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <time.h>
    #include <ctype.h>
    
    #define TENTHS 1
    #define PROMPT "What is your name?\n"
    #define MAX 60
    
    void do_endwin(void) {endwin();}
    
    int main()
    {	
    	if (initscr() == NULL) {
    		fprintf(stderr, "Could not initialize screen\n");
    		exit(EXIT_FAILURE);
    	}
    	atexit(do_endwin);
    	halfdelay(TENTHS);			// halfdelay mode ON
    	keypad(stdscr, TRUE);		// keypad mode ON
    	noecho();					// echo mode OFF
    
    	// Parameters for custom input routine
    	int timeout = 10;
    	char buf[MAX] = {'\0'};
    	bool timeout_occured = false;
    
    	// Begin custom input routine
    	// Show PROMPT and receive input from the user into buf
    	// Abort if timeout seconds have elapsed; in this case timeout_occured
    	// is set to true
    	// Up to MAX-1 characters may be typed or stored in buf
    	printw(PROMPT);
    	refresh();
    	time_t now = time(NULL);
    	int i=0;
    	for (;;) {
    		// check for timeout
    		time_t diff = time(NULL) - now;
    		struct tm *t = localtime(&diff);
    		if (t->tm_sec >= timeout) {
    			timeout_occured = true;
    			buf[i] = '\0';
    			break;
    		}
    					
    		// Read a character into ch and check for various errors
    		// ERR is not really an error; it just means there was no input yet
    		// erasechar() returns this terminal's "erase key" (e.g. backspace)
    		int ch = getch();
    		if (ch == ERR) { 
    			continue;
    		}else if (ch == erasechar() && i==0) { // erase key at line start
    			flash();
    			continue;
    		}else if (ch == erasechar()) { // erase key at non-line start
    			i--;
    			printw("%c %c", ch, ch); // delete the previous character
    			refresh();
    			continue;
    		}else if (ch == '\n') { // newline was pressed
    			buf[i] = '\0';
    			break;
    		}else if (iscntrl(ch)) { // control key (e.g. CTRL-C) pressed
    			flash();
    			continue;
    		}else if (ch != (char)ch) { // non-character key pressed
    			flash();
    			continue;
    		}else if (i == MAX-1) { // other key pressed but no more room in buf
    			flash();
    			continue;
    		}
    		
    		// store and echo the character
    		buf[i++] = ch;		
    		printw("%c", ch);
    		refresh();
    	}
    	printw("\n");
    	refresh();
    	// End custom input routine
    	
    	// Results of the custom input routine
    	printw("\nContents of buf:\n");
    	printw("%s\n", buf);
    	printw("\nTimeout occured: %s\n", timeout_occured ? "YES" : "NO");
    	refresh();
    	
    	// Print message and wait for user to press a key
    	printw("Press any key to end the program...");
    	refresh();
    	while (true) {
    		int ch = getch();
    		if (ch == ERR)
    			continue;
    		break;
    	}
    	exit(EXIT_SUCCESS);
    }
    To actually use the custom input routine in your quiz program, one should rewrite it as a reusable function, to be called with something like get_answer(prompt, timeout, &timeout_occured). Each time a new question occurs, update the value of timeout as appropriate based on how much total time is remaining. If timeout_occured is true, the user ran out of time and it's time to do the grading.
    Last edited by c99tutorial; 12-30-2012 at 05:29 AM.

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    54
    please attach curses.h and stdbool.h here to download. Thanks

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You can search the Web for ncurses and/or pdcurses. <stdbool.h> would already be available to you if your compiler (mostly) conforms to the 1999 edition of the C standard (or later), though you may need to pass a compiler option to enable that support. If not, you can remove that header inclusion and use 1 instead of true and 0 instead of false.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to get remaining time in downloading
    By Bargi in forum Windows Programming
    Replies: 1
    Last Post: 07-15-2008, 02:38 AM
  2. problems how to carry out the remaining balance
    By omarbags in forum C Programming
    Replies: 29
    Last Post: 01-30-2008, 03:58 PM
  3. remaining input from getch()
    By PierreB in forum C Programming
    Replies: 6
    Last Post: 03-25-2004, 02:10 PM
  4. estimating time remaining
    By Compengineer in forum C++ Programming
    Replies: 6
    Last Post: 05-25-2003, 09:38 AM