FAQ > How can I get input without having the user hit [Enter]?


Match word(s).

If you have any questions or comments,
please visit us on the Forums.

FAQ > How do I... (Level 2) > How can I get input without having the user hit [Enter]?

This item was added on: 2003/02/19

Using standard C/C++, you cannot. However, if you're lucky your compiler may have the non-standard conio.h header (which might include getch()), if you're on *nix (UNIX, Linux, etc.) you can try the ncurses library or switching the terminal mode. On Windows, try the different API input routines (such as those included in the Win32 API).


#include <stdio.h> 
#include <conio.h> 

int main()
{
  int ch;

  puts ("Press any key, q to quit");  
  
  while ((ch = getch()) != EOF && ch != 'q')
    printf ("%c\n", ch);

  return 0;
}



/*
 *  An example of how to obtain unbuffered
 *  input using the conio.h library and getch()
 */
#include <stdio.h> 
#include <conio.h> 
#include <ctype.h> 

int main()
{
  int ch;
  char pword[BUFSIZ];
  int i = 0;
  
  puts ("Enter your password");
  fflush(stdout);
  
  while ((ch = getch()) != EOF 
          && ch != '\n' 
          && ch != '\r' 
          && i < sizeof(pword) - 1)
  {
    if (ch == '\b' && i > 0) 
    {
      printf("\b \b");
      fflush(stdout);
      i--;
      pword[i] = '\0';
    }
    else if (isalnum(ch))
    {
      putchar('*');
      pword[i++] = (char)ch;
    }
  }

  pword[i] = '\0';
  
  printf ("\nYou entered >%s<", pword);
  
  return 0;
}

/*
 * Program output
 Enter your password
 ********
 You entered >security<
 
 *
 */


And now for a Windows specific solution:

// Code supplied by LuckY

#include <iostream> 
#include <windows.h> 

bool keyHit(void)
{
  HANDLE  stdIn = GetStdHandle(STD_INPUT_HANDLE);

  DWORD   saveMode;
  GetConsoleMode(stdIn, &saveMode);
  SetConsoleMode(stdIn, ENABLE_PROCESSED_INPUT);

  bool  ret = false;

  if (WaitForSingleObject(stdIn, 1) == WAIT_OBJECT_0) ret = true;

  SetConsoleMode(stdIn, saveMode);

  return(ret);
}

bool getChar(TCHAR &ch)
{
  bool    ret = false;

  HANDLE  stdIn = GetStdHandle(STD_INPUT_HANDLE);

  DWORD   saveMode;
  GetConsoleMode(stdIn, &saveMode);
  SetConsoleMode(stdIn, ENABLE_PROCESSED_INPUT);

  if (WaitForSingleObject(stdIn, INFINITE) == WAIT_OBJECT_0)
  {
    DWORD num;
    ReadConsole(stdIn, &ch, 1, &num, NULL);

    if (num == 1) ret = true;
  }

  SetConsoleMode(stdIn, saveMode);

  return(ret);
}

TCHAR getChar(void)
{
  TCHAR ch = 0;
  getChar(ch);
  return(ch);
}

int main(void)
{
  std::cout << "Press a key" << std::endl;
  getChar();
  std::cout << "Done" << std::endl;
}


For an example of switching terminal modes in *nix, check out this FAQ entry, where vVv supplied a mygetch() function that can be used in place of the getch() from conio.h.

Credit: Eibro (code by Hammer)

Script provided by SmartCGIs