How do I get my program to wait for a keypress?


Match word(s).

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

FAQ > How do I... (Level 1) > How do I get my program to wait for a keypress?

This item was added on: 2003/01/17

Most of the time people ask for this, they are wanting something to mimic the "pause" command in Windows or DOS, where the user sees "Press any key to continue . . .". Unfortunately, there isn't a standard way to do this in either C or C++. Most input streams are buffered, meaning the program will not usually see any data until the user presses [Enter].

The first few code snippets shown here use standard functions only, making them clean and portable. At the end, you'll find some non-standard implementations, that may or may not work for you. If you can't find something that works, go to the forums and try a search or two.

A C implementation:

This implementation is actually two functions. The problem is that if the stream is not empty, calling mypause will fail to work because getchar will read a character that's already present instead of block. However, if the stream is empty, calling myflush first will cause two blocks: first for the flush, and then for the pause. So the two are used alone or together at the appropriate time to work for most cases:

#include <stdio.h>

void myflush ( FILE *in )
{
  int ch;

  do
    ch = fgetc ( in ); 
  while ( ch != EOF && ch != '\n' ); 

  clearerr ( in );
}

void mypause ( void ) 
{ 
  printf ( "Press [Enter] to continue . . ." );
  fflush ( stdout );
  getchar();
} 

int main ( void )
{
  int number;

  // Test with an empty stream
  printf ( "Hello, world!\n" );
  mypause();

  // Leave extra input in the stream
  printf ( "Enter more than one character" );

  myflush ( stdin );
  mypause();

  return 0;
}

A C++ Implementation:

Identical to the C implementation except using C++ features. Notice the convenience of IOStreams in this example compared to the more manual techniques in the C version:

#include <ios>      // Required for streamsize
#include <iostream>
#include <istream>
#include <limits>   // Required for numeric_limits

void myflush ( std::istream& in )
{
  in.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
  in.clear();
}

void mypause() 
{ 
  std::cout<<"Press [Enter] to continue . . .";
  std::cin.get();
} 

int main()
{
  int number;

  // Test with an empty stream
  std::cout<<"Hello, world!\n" ;
  mypause();

  // Leave extra input in the stream
  std::cout<<"Enter more than one character" ;

  myflush ( std::cin );
  mypause();

  std::cin.get();
}

A poor-mans method of using system, OS specific:

#include <stdlib.h>

int main( void )
{
  system ( "PAUSE" );

  return 0;
}

A compiler specific implementation using getch:

#include <stdio.h>
#include <conio.h> /* for getch(), non-portable */

int main ( void )
{
   printf ( "Press any key to continue . . ." );
   getch();

   return 0;
}

A Unix specific method using terminal modes (Credit vVv)

This code attempts to mimic the getch function within DOS. It sets the terminal into non-canonical mode, thus disabling line buffering, reads a character from stdin and then restores the old terminal status. For more info on what else you can do with termios, see "man termios".

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch ( void ) 
{
  int ch;
  struct termios oldt, newt;
  
  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
  
  return ch;
}

There's also a getch function in the curses library, but it is not equivalent to the DOS getch and may only be used within real curses applications (ie: it only works in curses "WINDOW"s).

Script provided by SmartCGIs