104

I am trying to write a C++ program in which when user enter any character from keyboard and it should move to next line of code.

Here is my code:

char c;

cin>>c;

cout<<"Something"<<endl;

but this is not working, because it only move to next line when I input some character and then press ENTER.

OR

If I use this

cin.get() or cin.get(c)

it move to next line of instruction when I press Enter.

But I wanted it to move to next line on any key pressed on the keyboard, how this can be done?

johnnyRose
  • 7,310
  • 17
  • 40
  • 61
itsaboutcode
  • 24,525
  • 45
  • 110
  • 156
  • As far as I know, the problem is, that your shell is waiting for you to press ENTER or EOF and then will let your program take care of whatever is in the buffer, or something like this. Maybe somebody with some more knowledge could provide a real explanation. But I think it is not as easy as it first appears. – Lucas Sep 19 '09 at 21:02
  • 7
    By far the easiest way to handle this, and the only portable way, is to change your prompt from “Press any key to continue” to “Press the Enter key to continue”. – rob mayoff Feb 23 '12 at 04:44
  • @Lucas - I am using mac with xcode. – itsaboutcode Feb 23 '12 at 19:25
  • @Lucas: It's not the shell, it's the program itself. – Keith Thompson Feb 23 '12 at 19:25
  • @KeithThompson: This is more than two years ago, but I think I was trying to make the point that the input queue doesn't get handled by the user process but inside the Kernel. – Lucas Feb 24 '12 at 03:13

15 Answers15

79

On Windows:

system("pause");

and on Mac and Linux:

system("read");

will output "Press any key to continue..." and obviously, wait for any key to be pressed. I hope thats what you meant

MrMartin
  • 411
  • 5
  • 18
  • I think the problem was that he doesn't use windows. – Lucas Sep 21 '09 at 10:58
  • 9
    `system` calls external program. You don't have to call external program to wait for any key! It's like calling another person to turn on your computer when you're sitting in front of it - this is slow solution. – GingerPlusPlus Aug 25 '14 at 09:51
  • 10
    True, but it's only one line long! Sometimes it's just not worth the effort to save the computer some cycles... – Elliot Cameron Nov 24 '14 at 17:02
  • 21
    Forget slow, it calls the first program named "pause" it happens to find in PATH, and gives it the calling program's privilege level. Even if you're a student just testing your own code, it's still a massive security risk. – Anne Quinn Dec 14 '14 at 11:11
  • @Clairvoire Would you care to explain it in some more detail, as I currently am that student testing his own code ^^ – XD face me Jan 27 '15 at 21:05
  • 6
    @XDfaceme - pause is an actual program that system() asks windows to run. If however, there's another program called 'pause' and windows finds that program first, it will run it instead. I suppose I might've overblown the significance a little, but it's still easier to just use cin.get() and hit return to pause/unpause a program – Anne Quinn Jan 27 '15 at 23:32
  • @Clairvoire, see [system Function](https://msdn.microsoft.com/en-us/library/b4b6wz4t.aspx). It is an "internal operating system command"; no searching. Then see [MS-DOS 5.0 Internal and External Commands](https://support.microsoft.com/en-us/kb/71986). That article **is** about DOS but the Windows command processor is the same in this context. "Pause" is an Internal Command and therefore it is not possible for some other program to execute. I do however agree that system("pause") is ridiculous overkill. It is an easy answer but once we know what else to use then the alternative is easy. – Sam Hobbs Apr 29 '16 at 05:17
  • 2
    I am not a fan of absolutes. Making a blanket statement that system("pause") is a security risk and that it is bad even when testing your own code is blowing things way out of proportion here. cin.get() might be the right solution, but it does not solve the question that was being asked... cin.get() only responds after "enter" or "return" are pressed. The question specifically was to respond to any key press. system("pause") does exactly that. First of all, the only place where I have seen this as useful is in a dev class when debugging from Visual Studio, so I think that system("pause") works – Gregor Sep 04 '17 at 23:07
  • Absolutely horrified to see my own comment make such an ignorant statement. I have come full circle in the 6 year interim, `system("pause")` is an *excellent* choice for this purpose. – Anne Quinn Jul 20 '21 at 11:19
58

If you're on Windows, you can use kbhit() which is part of the Microsoft run-time library. If you're on Linux, you can implement kbhit thus (source):

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

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

Update: The above function works on OS X (at least, on OS X 10.5.8 - Leopard, so I would expect it to work on more recent versions of OS X). This gist can be saved as kbhit.c and compiled on both Linux and OS X with

gcc -o kbhit kbhit.c

When run with

./kbhit

It prompts you for a keypress, and exits when you hit a key (not limited to Enter or printable keys).

@Johnsyweb - please elaborate what you mean by "detailed canonical answer" and "all the concerns". Also, re "cross-platform": With this implementation of kbhit() you can have the same functionality in a C++ program on Linux/Unix/OS X/Windows - which other platforms might you be referring to?

Further update for @Johnsyweb: C++ applications do not live in a hermetically sealed C++ environment. A big reason for C++'s success is interoperability with C. All mainstream platforms are implemented with C interfaces (even if internal implementation is using C++) so your talk of "legacy" seems out of place. Plus, as we are talking about a single function, why do you need C++ for this ("C with classes")? As I pointed out, you can write in C++ and access this functionality easily, and your application's users are unlikely to care how you implemented it.

Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191
  • 1
    It's a shame that there is not standard way to handle the console, you always have to use some OS magick – Vargas Sep 20 '09 at 00:29
  • True. Consoles have been de-emphasised since the advent of GUIs. – Vinay Sajip Sep 20 '09 at 07:42
  • "The question is widely applicable to a large audience. A detailed canonical answer is required to address all the concerns." is StackOverflow's wording. I wanted to emphasise **C++** and not rely on legacy C headers and function calls, since the question is tagged with C++. – johnsyweb Feb 20 '12 at 08:33
  • @Johnsyweb: There is nothing 'legacy' about the function calls or headers here. What you want can't be done in standard C++, or even a widely portable superset. – Managu Feb 22 '12 at 02:35
  • @Managu: I appreciate that [there is nothing in the language or in the standard library](http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.17) to do this, but I don't believe it's *impossible* to implement in C++. – johnsyweb Feb 23 '12 at 08:01
  • @Johnysweb: Could you further elaborate in what way you find Vinay Sajip's solution unsatisfactory? Something specific, e.g. "I'd like a solution which doesn't use anything from ``;" or maybe "I need compatibility with iostreams.". – Managu Feb 23 '12 at 20:20
  • Thanks. I think this is the best and most comprehensive answer. FWIW, I would probably have implemented something like [this](https://gist.github.com/1910950). – johnsyweb Feb 25 '12 at 21:30
  • 1
    @Johnsyweb: Thank *you*, but your example shows features that depress me about C++. Your `kbhit()` function declares a `terminal_settings` variable in a line which appears to do nothing, and yet it does everything. Some might think it's neat, but I find it to be obscure to the point of unreadability. – Vinay Sajip Feb 25 '12 at 23:05
  • 1
    @VinaySajip: My implementation uses [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization), which is one of the most important idioms in C++. While it's not strictly necessary in this example, I've found it a good habit to get into when you want to save some state and restore it. – johnsyweb Feb 26 '12 at 02:00
  • 4
    @Johnsyweb: I'm aware of RAII and the benefits it brings, I'm an old C++ hand myself. My point remains: there's no clear connection between the declaration and what it's doing behind the scenes. While it might be using shiny C++ idioms rather than plain old C, my view is that it does little to illuminate and much to obscure what's going on. This is not directed at you personally in any way - it's just an opinion about how C++ can be used to create code which is unnecessarily hard to understand. I'll get off my soapbox now, 'nuff said. – Vinay Sajip Feb 26 '12 at 21:53
  • 2
    It's nice and all, but still catches any previous garbage on the stdin :-) – Tiago Mar 25 '15 at 15:52
10

There is no completely portable solution.

Question 19.1 of the comp.lang.c FAQ covers this in some depth, with solutions for Windows, Unix-like systems, and even MS-DOS and VMS.

A quick and incomplete summary:

  • You can use the curses library; call cbreak() followed by getch() (not to be confused with the Windows-specific getch()function). Note that curses generally takes control of the terminal, so this is likely to be overkill.
  • You might be able to use ioctl() to manipulate the terminal settings.
  • On POSIX-compliant systems, tcgetattr() and tcsetattr() may be a better solution.
  • On Unix, you can use system() to invoke the stty command.
  • On MS-DOS, you can use getch() or getche().
  • On VMS (now called OpenVMS), the Screen Management (SMG$) routines might do the trick.

All these C solutions should work equally well in C++; I don't know of any C++-specific solution.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 2
    All these multi-platform solutions could do with someone writing a function that is implemented to do the right thing dependent on your platform with lots of pre-processors to determine what that platform is. – CashCow Jan 21 '14 at 16:21
  • @CashCow "With lots of pre-processors"?! My approach usually is 1 header file and then a bunch of platform specific implementations with NO pre-processors beyond the `#include`. Then, you just pick the right implementation file at build time and you are done. – BitTickler Aug 26 '22 at 07:12
6

In windows, this short program accomplishes the goal: getch pauses the console until a key is pressed (https://www.geeksforgeeks.org/difference-getchar-getch-getc-getche/)

#include<iostream.h>
#include<conio.h>

using namespace std;

void  check()
{
    char chk; int j;
    cout<<"\n\nPress any key to continue...";
    chk=getch();
    j=chk;
    for(int i=1;i<=256;i++)
      if(i==j) break;
    clrscr();
}

void main()
{
    clrscr();
    check();
    cout<<"\n\nIt works!";
    getch();
}

It should be noted that getch is not part of the standard library.

BoldX
  • 61
  • 1
  • 4
6

You could use the Microsoft-specific function _getch:

#include <iostream>
#include <conio.h>
// ...
// ...
// ...
cout << "Press any key to continue..." << endl;
_getch();
cout << "Something" << endl;
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Salman A
  • 262,204
  • 82
  • 430
  • 521
5

To achieve this functionality you could use ncurses library which was implemented both on Windows and Linux (and MacOS as far as I know).

Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
5

I looked into what you are trying to achieve, because I remember I wanted to do the same thing. Inspired by Vinay I wrote something that works for me and I sort of understand. But I am not an expert, so please be careful.

I don't know how Vinay knows you are using Mac OS X. But it should work kind of like this with most unix-like OS. Really helpful as resource is opengroup.org

Make sure to flush the buffer before using the function.

#include <stdio.h>
#include <termios.h>        //termios, TCSANOW, ECHO, ICANON
#include <unistd.h>     //STDIN_FILENO


void pressKey()
{
    //the struct termios stores all kinds of flags which can manipulate the I/O Interface
    //I have an old one to save the old settings and a new 
    static struct termios oldt, newt;
    printf("Press key to continue....\n");

    //tcgetattr gets the parameters of the current terminal
    //STDIN_FILENO will tell tcgetattr that it should write the settings
    // of stdin to oldt
    tcgetattr( STDIN_FILENO, &oldt);
    //now the settings will be copied 
    newt = oldt;

    //two of the c_lflag will be turned off
    //ECHO which is responsible for displaying the input of the user in the terminal
    //ICANON is the essential one! Normally this takes care that one line at a time will be processed
    //that means it will return if it sees a "\n" or an EOF or an EOL
    newt.c_lflag &= ~(ICANON | ECHO );      

    //Those new settings will be set to STDIN
    //TCSANOW tells tcsetattr to change attributes immediately. 
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    //now the char wil be requested
    getchar();

    //the old settings will be written back to STDIN
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);

}


int main(void)
{
  pressKey();
  printf("END\n");
  return 0;
}

O_NONBLOCK seems also to be an important flag, but it didn't change anything for me.

I appreciate if people with some deeper knowledge would comment on this and give some advice.

Community
  • 1
  • 1
Lucas
  • 13,679
  • 13
  • 62
  • 94
  • O_NONBLOCK should be set because without it, getchar() (which calls read()) will block waiting for input. The kbhit() solution tells if you a key is hit, without waiting; you can use it in a wait loop or for any other purpose, so it's a more general solution. A solution without O_NONBLOCK will wait until a key is hit - OK for this question but less generally useful. – Vinay Sajip Sep 20 '09 at 07:41
4

If you're using Visual Studio 2012 or older, use the getch() function, if you are using Visual Studio 2013 or newer, use _getch(). You will have to use #include <conio.h>. Example:

#include <iostream>
#include <conio.h>

int main()
{
   std::cout << "Press any key to continue. . .\n";
   _getch(); //Or getch()
}
rayryeng
  • 102,964
  • 22
  • 184
  • 193
John Doe
  • 161
  • 1
  • 2
  • 8
3

This works on a Windows Platform: It Uses the Microprocessor registers directly and can be used to check key press or mousebutton

    #include<stdio.h>
    #include<conio.h>
    #include<dos.h>
    void main()
    {
     clrscr();
     union REGS in,out;
     in.h.ah=0x00;
     printf("Press any key : ");

     int86(0x16,&in,&out);
     printf("Ascii : %d\n",out.h.al);
     char ch = out.h.al;
     printf("Charcter Pressed : %c",&ch);
     printf("Scan code : %d",out.h.ah);
     getch();
    }
Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
2

You can use the getchar routine.

From the above link:

/* getchar example : typewriter */
#include <stdio.h>

int main ()
{
  char c;
  puts ("Enter text. Include a dot ('.') in a sentence to exit:");
  do {
    c=getchar();
    putchar (c);
  } while (c != '.');
  return 0;
}
Nick Dandoulakis
  • 42,588
  • 16
  • 104
  • 136
  • 3
    I don't think this is what the OP was asking for, if I understand him correctly. You still have to press ENTER to fill the buffer before getchar() can read from it. – Lucas Sep 19 '09 at 20:47
0

Another option is using threads with function pointers:

#include <iostream>
#include <thread> // this_thread::sleep_for() and thread objects
#include <chrono> // chrono::milliseconds()

bool stopWaitingFlag = false;

void delayms(int millisecondsToSleep) 
{
  std::this_thread::sleep_for(std::chrono::milliseconds(millisecondsToSleep));
}

void WaitForKey() 
{
  while (stopWaitingFlag == false)
  {
    std::cout<<"Display from the thread function"<<std::endl;
    delayms(1000);
  }
}

 

int main()
{
  std::thread threadObj(&WaitForKey);

  char userInput = '\0';
  while (userInput != 'y')
  {
    std::cout << "\e[1;31mWaiting for a key, Enter 'y' for yes\e[0m" << std::endl;
    std::cin >> userInput;
    if (userInput == 'y') {
      stopWaitingFlag = true;
    }
  }
  if (threadObj.joinable())
    threadObj.join();

  std::cout<<"Exit of Main function"<<std::endl;
  return 0;
}
wgaonar
  • 11
  • 2
0

Also you can use getch() from conio.h. Just like this:

...includes, defines etc
void main()
{
//operator
getch(); //now this function is waiting for any key press. When you have pressed its     just     //finish and next line of code will be called
}

So, because UNIX does not have conio.h, we can simulate getch() by this code (but this code already written by Vinary, my fail):

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

int mygetch( ) {
  struct termios oldt,
             newt;
  int            ch;
  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;
}
John Doe
  • 161
  • 1
  • 2
  • 8
m9_psy
  • 3,217
  • 5
  • 25
  • 38
-2

If you look up kbhit() function on MSDN now, it says the function is deprecated. Use _kbhit() instead.

#include <conio.h>
int main()
{
    _kbhit();
    return 0;
}
BG4WCE
  • 9
  • 1
-2
#include <iostream>
using namespace std;

int main () {
    bool boolean;
    boolean = true;

    if (boolean == true) {

        cout << "press any key to continue";
        cin >> boolean;

    }
    return 0;
}
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
-6

Just use the system("pause"); command.

All the other answers over complicate the issue.

ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
Chad
  • 7