Reputation: 25099
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?
Upvotes: 105
Views: 208232
Reputation: 1
win 10 x64
file - main.c :
`extern void _getch (void) ;`
_getch ();
----------------------------------
C:\msys64\mingw64\bin\gcc -c ^
main.c -m64 -mabi=ms (create obj file main.o)
-----
C:\msys64\mingw64\bin\gcc -O0 -mconsole ^
-mabi=ms ^
-m64 -o state main.o ^
api-ms-win-crt-conio-l1-1-0.dll (create exe file state.exe)
-----------------------
c:\Program Files (x86)\Windows Kits\10\Redist\10.0.22000.0\ucrt\DLLs\x64\api-ms-win-crt-conio-l1-1-0.dll
copy this dll to project directory ( this dll contain _getch() )
Upvotes: -1
Reputation: 99425
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 it. Quoted from here, here it is:
#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.
Upvotes: 59
Reputation: 11
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;
}
Upvotes: 0
Reputation: 191
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()
}
Upvotes: 4
Reputation: 61
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.
Upvotes: 6
Reputation: 1
#include <iostream>
using namespace std;
int main () {
bool boolean;
boolean = true;
if (boolean == true) {
cout << "press any key to continue";
cin >> boolean;
}
return 0;
}
Upvotes: -2
Reputation: 9
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;
}
Upvotes: -2
Reputation: 3386
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;
}
Upvotes: 0
Reputation:
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
Upvotes: 79
Reputation: 7
Just use the system("pause");
command.
All the other answers over complicate the issue.
Upvotes: -6
Reputation: 263497
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:
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.ioctl()
to manipulate the terminal settings.tcgetattr()
and tcsetattr()
may be a better solution.system()
to invoke the stty
command.getch()
or getche()
.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.
Upvotes: 12
Reputation: 272256
You could use the Microsoft-specific function _getch:
#include <iostream>
#include <conio.h>
// ...
// ...
// ...
cout << "Press any key to continue..." << endl;
_getch();
cout << "Something" << endl;
Upvotes: 5
Reputation: 11787
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();
}
Upvotes: 3
Reputation: 14129
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.
Upvotes: 6
Reputation: 43130
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;
}
Upvotes: 3
Reputation: 99635
To achieve this functionality you could use ncurses library which was implemented both on Windows and Linux (and MacOS as far as I know).
Upvotes: 5