Thread: detecting enter w/o locking display

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    5

    detecting enter w/o locking display

    Hey,

    ok, first I must admit that this is homework - but I have tried to figure it out and have gotten nowhere in the last 6 hours (plus it is a small part of the overall project - building a virtual submarine)

    I will use threads to allow different parts of the program to run concurrently. The change in status of each thread will be displayed for the user (example: depth). The user presses enter to lock the display and enter commands.

    How do I check if the user has pressed enter without locking the display to get input from stdin?

    Thanks in advance,
    Dave.

  2. #2
    Quote Originally Posted by dgates
    ok, first I must admit that this is homework - but I have tried to figure it out and have gotten nowhere in the last 6 hours (plus it is a small part of the overall project - building a virtual submarine)

    I will use threads to allow different parts of the program to run concurrently. The change in status of each thread will be displayed for the user (example: depth). The user presses enter to lock the display and enter commands.

    How do I check if the user has pressed enter without locking the display to get input from stdin?
    Sounds to be a nice simulation program.

    There is no standard way to get an entry without a suspension of the execution. But isn't it exactly the purpose of muti-threading? You have a an input thread that is suspended during the moment when no entry is available. It will trig when a input is ready.

    That said, I understand that you probably want a more reactive mechanism.

    Some systems and compilers offer facilities. Compilers targetting MS-DOS or Windows in console mode often provide the conio library. Have a look to kbhit() and getch().

    Others systems (like Windows GUI, or Linux/Gtk+) have event driven mechanisms specially designed for the purpose.

    You should be more accurate about your environment.
    Emmanuel Delahaye

    "C is a sharp tool"

  3. #3
    Registered User
    Join Date
    Jul 2004
    Posts
    5
    Sorry about that - I am working on Solaris.

    Your comment about using an input thread made me think of a possible solution:

    - Have the main thread spawn another thread which will block if there is no input from stdin.
    - Within a loop have the parent thread update the screen and then awaken the input thread.
    - The input thread blocks if enter has not been pressed, and the loop continues
    - If enter has been pressed then the input thread locks the display to get the command

    Going to try coding it now. Thanks again.

    Dave.

    PS this is only the second program I have written with threads - so if you see any flaws in my idea, or know of any shortcuts, input would be most appreciated.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jul 2004
    Posts
    5
    I checked those out earlier... The C implimentation using getchar allows for pressing enter to continue - I need to continue displaying stuff until the enter key is pressed and then get input from the user. The Unix specific method I just don't understand....

  6. #6
    Registered User linuxdude's Avatar
    Join Date
    Mar 2003
    Location
    Louisiana
    Posts
    926
    Do you want something like select()?
    Code:
             /*chose one of these two*/
           /* According to POSIX 1003.1-2001 */
                  #include <sys/select.h>
    
                  /* According to earlier standards */
                #include <sys/time.h>
                #include <sys/types.h>
                #include <unistd.h>
    
                    fd_set rfds;
                    struct timeval tv;
                    FD_ZERO(&rfds);
    
                    FD_SET(0, &rfds);
                    tv.tv_sec = 5; /*seconds to wait*/
                    tv.tv_usec = 0; /*microseconds*/
                    retval=select(1, &rfds, NULL, NULL, &tv);
                    canswer=ln*bn;
                    if(retval){
                      /*if user did something then hit enter*/
                    }
                            else{
                           /*they didn't hit anything*/
                            }
                    }
    Thank Thantos for helping me with this one earlier. here is the thread

  7. #7
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Here's a complete sample of the select function. User WaitForInput(0) to simulate a poll to stdin.

    Code:
     #include <stdio.h>
     #include <sys/time.h>
     #include <sys/types.h>
     #include <unistd.h>
     
     int WaitForInput (int seconds)
     {
       /* 
        * Waits n seconds for input.
        * returns
        *  -1 on error
        *   0 on no input
        *  >0 on input available
        *
        * When seconds == 0, the program will 
        * wait for a fraction of a second.
        */
        
       fd_set          fdset;
       struct timeval  timeout;
       int             res;
     
       FD_ZERO(&fdset);
       FD_SET(fileno(stdin), &fdset);
     
       timeout.tv_sec = seconds;
       timeout.tv_usec = (seconds ? 0 : 100);
     
       res = select(fileno(stdin) + 1, &fdset, 0, 0, &timeout);
      
       switch (res)
       {
         case -1:
           perror ("select");
           break;
         case  0:
           break;
         default:
           res = FD_ISSET(fileno(stdin), &fdset);
           break;
       }
           
       return res;
     }
     
     int main(void)
     {
       printf ("Waiting for you to press enter...\n");
       
       if (WaitForInput (1) > 0)
       {
         puts ("Congrats");
       } 
       else
       {
         puts ("Too slow!");
       }
       
       return 0;
     }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  8. #8
    Registered User
    Join Date
    Jul 2004
    Posts
    5
    Hey good news!

    Enough people had problems with this part that my instructor posted the code, so I am posting it here in case anyone can use it. I tried to cut out all that did not pertain, if I missed anything (cut out too much) let me know and I will add it.

    Code:
    #include <pthread.h>
    #include <string.h>
    
    pthread_mutex_t g_DisplayMutex;
    pthread_mutex_t	g_DisplayMutex = PTHREAD_MUTEX_INITIALIZER;
    
    int main ( int argc, char *argv[] ){
    /* Signon message -- no need for mutex yet... */
    	printf ("Sub Control V0.1 started.\n");
    	fflush (stdout);
    
            for ( ; ; ){
    		char commandBuffer[256];
    
    		fgets (commandBuffer, 255, stdin );
    		/* Aquire mutex */
    		pthread_mutex_lock ( &g_DisplayMutex );
    		printf ("Enter Command:");
    		fflush (stdout);
    		fgets (commandBuffer, 255, stdin );
    		
    		printf ("Command received: %s\n", commandBuffer );
    		fflush(stdout);
    		pthread_mutex_unlock ( &g_DisplayMutex );
    		/* Free mutex */
    	}
    
    	return 0;
    }

  9. #9
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>How do I check if the user has pressed enter without locking the display to get input from stdin?
    The code you've provided doesn't do that (at least not that I can see from what you've posted). The call to fgets() is going to block for input, and I guess the mutex locks are going to stop the other threads whilst they're in place? Oh well, if it works for you, then good luck with it.

    On a side note, fgets() allows for the \0 byte, so the second parameter should be 256, not 255. Or even better, use sizeof(commandBuffer) if the array is within scope.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  10. #10
    Registered User
    Join Date
    Jul 2004
    Posts
    5
    If you would like to check out the code he gave us it is at:

    http://gandalf.csc.uvic.ca/csc360/

    then go to the sample project link for assignment 3.

    The prof is in the process of setting the site up so you have to log in, so I don't know how long this link will be avaliable.

    it does include a make file, but I don't know if this will work on your machine... if you are missing files I will see if I can get them off the school server - that section you do have to log into and I may not have permission to download the needed file.

    Dave.
    Last edited by dgates; 07-07-2004 at 09:26 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with switch statements
    By Wexy in forum C Programming
    Replies: 3
    Last Post: 11-06-2002, 05:44 PM
  2. I need help badly
    By taz_jiggy in forum C++ Programming
    Replies: 4
    Last Post: 04-23-2002, 09:36 PM
  3. Enter Char w/o having to press [Return]
    By Okiesmokie in forum C++ Programming
    Replies: 11
    Last Post: 02-17-2002, 02:22 PM
  4. terminate 0 - PLEASE HELP
    By Unregistered in forum C Programming
    Replies: 11
    Last Post: 11-21-2001, 07:30 AM
  5. Desperate for help - ugly nested if
    By baseballkitten in forum C Programming
    Replies: 4
    Last Post: 11-19-2001, 03:56 PM