home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / cgets.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  4KB  |  119 lines

  1. /***
  2. *cgets.c - buffered keyboard input
  3. *
  4. *       Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines _cgets() - read a string directly from console
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <cruntime.h>
  12. #include <oscalls.h>
  13. #include <mtdll.h>
  14. #include <conio.h>
  15. #include <stdlib.h>
  16. #include <internal.h>
  17.  
  18. /*
  19.  * mask to clear the bits required to be 0 in the handle state passed to
  20.  * DOSSETFHSTATE.
  21.  */
  22. #define FHSTATEMASK 0xffd07888
  23.  
  24. /*
  25.  * declaration for console handle
  26.  */
  27.  
  28. extern int _coninpfh;
  29.  
  30.  
  31. /***
  32. *char *_cgets(string) - read string from console
  33. *
  34. *Purpose:
  35. *       Reads a string from the console via ReadConsole on a cooked console
  36. *       handle.  string[0] must contain the maximum length of the
  37. *       string.  Returns pointer to str[2].
  38. *
  39. *       NOTE: _cgets() does NOT check the pushback character buffer (i.e.,
  40. *       _chbuf).  Thus, _cgets() will not return any character that is
  41. *       pushed back by the _ungetch() call.
  42. *
  43. *Entry:
  44. *       char *string - place to store read string, str[0] = max length.
  45. *
  46. *Exit:
  47. *       returns pointer to str[2], where the string starts.
  48. *       returns NULL if error occurs
  49. *
  50. *Exceptions:
  51. *
  52. *******************************************************************************/
  53.  
  54. char * __cdecl _cgets (
  55.         char *string
  56.         )
  57. {
  58.         ULONG oldstate;
  59.         ULONG num_read;
  60.         char *result;
  61.  
  62.         _mlock(_CONIO_LOCK);            /* lock the console */
  63.  
  64.         string[1] = 0;                  /* no chars read yet */
  65.         result = &string[2];
  66.  
  67.         /*
  68.          * _coninpfh, the handle to the console input, is created the first
  69.          * time that either _getch() or _cgets() or _kbhit() is called.
  70.          */
  71.  
  72.         if ( _coninpfh == -2 )
  73.             __initconin();
  74.  
  75.         if ( _coninpfh == -1 ) {
  76.             _munlock(_CONIO_LOCK);      /* unlock the console */
  77.             return(NULL);               /* return failure */
  78.         }
  79.  
  80.         GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
  81.         SetConsoleMode( (HANDLE)_coninpfh, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
  82.                                          ENABLE_ECHO_INPUT );
  83.  
  84.         if ( !ReadConsole( (HANDLE)_coninpfh,
  85.                            (LPVOID)result,
  86.                            (unsigned char)string[0],
  87.                            &num_read,
  88.                            NULL )
  89.            )
  90.             result = NULL;
  91.  
  92.         if ( result != NULL ) {
  93.  
  94.             /* set length of string and null terminate it */
  95.  
  96.             if (string[num_read] == '\r') {
  97.                 string[1] = (char)(num_read - 2);
  98.                 string[num_read] = '\0';
  99.             } else if ( (num_read == (ULONG)(unsigned char)string[0]) &&
  100.                         (string[num_read + 1] == '\r') ) {
  101.                 /* special case 1 - \r\n straddles the boundary */
  102.                 string[1] = (char)(num_read -1);
  103.                 string[1 + num_read] = '\0';
  104.             } else if ( (num_read == 1) && (string[2] == '\n') ) {
  105.                 /* special case 2 - read a single '\n'*/
  106.                 string[1] = string[2] = '\0';
  107.             } else {
  108.                 string[1] = (char)num_read;
  109.                 string[2 + num_read] = '\0';
  110.             }
  111.         }
  112.  
  113.         SetConsoleMode( (HANDLE)_coninpfh, oldstate );
  114.  
  115.         _munlock(_CONIO_LOCK);          /* unlock the console */
  116.  
  117.         return result;
  118. }
  119.