How to display what key was pressed?
I mean, like if you press A, on screen will display: You pressed A.
cin>>keypress;
cout<<"You pressed:"<<keypress;
I want to show directly what key I am pressing. Without waiting to press enter and finishing the execution.
I have a Windows only solution using the windows api.
#include <wInDoWs.h>.
you can use GetAsyncKeyState() and pass the ASCII value for the key to it. It will return a short indicating the status of the button. To the best of my knowledge, the value -32767 is returned when the button is pressed. Wrap that in a function and you can tell if the button is pressed. (below will run with copy/paste.)
#include <windows.h>
#include <iostream>
bool pressed(const short& _key)
{
short state = 0;
short pressed= -32767;
state = GetAsyncKeyState( _key);
return ( state == pressed );
}
int main()
{
//see if J is pressed
while(1)
{
if(pressed( 0x4a ) )// 'J'
std::cout << "J";
}
}
To make that work with all characters, I'm afraid I can't think of an easier way than storing all the ASCII values, and what you want to print out if the key is pressed, in a container and checking their pressed status every frame.(below is just pseudo code.)
//the container this short is the 'key'
std::vector< std::pair< short , std::string > > chars;
//to check the status
for(auto& c : chars)
if( pressed( c.first ) ) std::cout << c.second;
I would put that in some sort of loop.
Adding the 'you pressed space' wouldn't be difficult this way.
just do
chars.push_back( std::pair<int,std::string>(0x20 , "Spacebar") );
I think you want to display the character what are you pressing (like in your example). So, it's pretty simple. Here's the code:
#include <stdio.h>
#include <conio.h>
int main()
{
char keyPress;
while(1)
{
keyPress=_getch();
if((keyPress==27)||(keyPress==32))
{
printf("You decided to stop the execution of this code.");
return 0;
}
printf("You pressed:%c\n",keyPress);
}
}
If you let the code how it is, the program will finish the execution on esc or space pressed. If you want to change this, you can replace the numbers in: if((keyPress==27)||(keyPress==32)) with anothers ascii codes of your button. Here's all the ascii codes: https://ascii.cl/ . If you want to end the program only on one button, just modify from if((keyPress==27)||(keyPress==32)) into if(keyPress==27) and now the program will stop only on ESC.
Related
I would like to use arrow keys user input without the user having to press enter every time after clicking the arrow. Therefore, I decided to use _getch(), which allegedly does exactly that. It is part of the conio.h library, which I imported. However, in my case,_getch() also requires the user to press enter and doesn't immediately register the user input, as it should've. How can I fix that? (I'm running on windows)
#include<iostream>
#include <conio.h>
using namespace std;
int main() {
int p = _getch();
cout<<p;
return 0;
}
For example, in the code above instead of directly printing the value of p after receiving input in the console, it still waits for enter to be pressed.
From Microsoft Docs:
When reading a function key or an arrow key, each function must be called twice; the first call returns 0 or 0xE0, and the second call returns the actual key code.
So a revised version of your code might look like this:
#include <iostream>
#include <conio.h>
int main() {
int p = 0;
while(p == 0 || p == 0xE0)
p = _getch();
std::cout << p;
return 0;
}
My program starts by entering any key,then the user sees a color changing text "Welcome to my
program". Now, the user should hit any key to continue, but he can't quit the infinite loop that is changing the color of text. Let me show you the code for a better understanding.
HANDLE color=GetStdHandle(STD_OUTPUT_HANDLE);
cout<<"Press any key to start...";
int stop=getchar();
while(stop){
for(i=10;i<=15;i++){
cout <<("\n\t\t\t\t\t Welcome to my program\n");
SetConsoleTextAttribute(color,i);
Sleep(100);
system("cls");
}
}
This would be a solution for you (comments included)
#include <iostream>
#include <Windows.h>
#include <thread>
int main()
{
HANDLE color = GetStdHandle( STD_OUTPUT_HANDLE );
std::cout << "Press any key to start...";
bool stop = false; // use a Boolean instead of int
// doesn't really matter what the input is, so use getchar().
// Note, this is really just "enter". You can modify if you expect user to
// hit multiple keys before hitting enter
getchar();
// This line here will start a new thread which will wait for the user to hit enter
std::thread getInput = std::thread( [&stop] { getchar(); stop = true; } );
// Loop stays the same (except I inverse the "stop" variable to make more sense)
while ( !stop ) {
for ( int i = 10; i <= 15; i++ ) {
std::cout << ( "\n\t\t\t\t\t Welcome to my program\n" );
SetConsoleTextAttribute( color, i );
Sleep( 100 );
system( "cls" );
}
}
}
When you are using getchar() to get input from the user, it will store inside the integer stop the decimal value of the buffer the user entered.
For example: if the user entered '0', the stop variable will store the value 48 (the decimal value of the char '0').
And you while loop will keep running while stop is not equal to 0, which is never because the decimal value of all of the characters is not 0, the only character that its decimal value is 0 is NULL.
To fix your problem you will need to add an exit option according to your needs.
If you create a loop as follows:
int myInt = 1;
while (myInt)
{
std::cin >> myInt;
}
The loop will continue until the user enters 0. This is because conditional statements use 0 as "false" and in this case, any other value as "true".
The problem with your implementation is you only get the users input once, and even if the user enters "0" (in char format) the integer value associated is 48.
You could add this:
HANDLE color=GetStdHandle(STD_OUTPUT_HANDLE);
cout<<"Press any key to start...";
int stop=getchar();
while(stop){
for(i=10;i<=15;i++){
cout <<("\n\t\t\t\t\t Welcome to my program\n");
SetConsoleTextAttribute(color,i);
Sleep(100);
system("cls");
}
std::cin >> stop;
}
Now the loop will start when the user presses any key, then the the inner loop will run, then the user will need to enter a key again. If the user enters "0" this time the while() loop will break and the program will proceed.
If you are trying to keep a loop running while searching for user input to break the loop, then you are attempting a much more complex task. Look into the std::thread library if you are interested in this.
The issue with your code from what I could tell is that you're only initializing the variable "stop" once in your code and never inside your loop. So, the program will only ask the user for input once. A simple fix would be to continuously ask the user for input at the end of your for loop:std::cin>>stop;. In addition, like what others have already said, if the user inputs '0', it would implicitly typecast the char variable into an integer variable using ASCII. Since '0' corresponds to the integer value of 48, it would save 48 into the variable instead of 0. You can fix this by using this code:
HANDLE color=GetStdHandle(STD_OUTPUT_HANDLE);
cout<<"Press any key to start...";
int stop=getchar()-'0';
while(stop){
for(i=10;i<=15;i++){
cout <<("\n\t\t\t\t\t Welcome to my program\n");
SetConsoleTextAttribute(color,i);
Sleep(100);
system("cls");
}
std::cin>>stop;
}
this is my code
#include <conio.h>
#include <iostream>
using namespace std;
int main() {
bool a = false;
char b='p';
int c=0;
while (a != true) {
if (_kbhit()) {
b = _getch();
}
if (b=='w') {
c++;
cout << c << " ";
}
else if (b == 'c') {
cout << "hello";
}
}
system("pause");
return 0;
}
The problem is where when I press 'w' I want it to print out the value of c and it should be repeating until i press another input for _kbhit() right? because now it add 1 to c then prints c and when i press w again samething. What's wrong with my visual studio I'm using community 2017 I've tried to uninstall it and install it again but same problem occurs.
The problem you're running into seems to be a result of a recently added bug in _getch()/_kbhit.
For an extended key (e.g., a cursor key) it's documented that _getch() returns either a 0x0 or 0xe0 followed by the scan code for the key that was actually pressed. What's not documented is that if the user presses a non-extended key, _kbhit will still return true twice in succession, and calls to _getch() will return the key code the first time, and 0x0 the second time.
In your code, when the user presses 'w' or 'c', _kbhit will return true not just once (as you'd expect) but twice. The first time you call it, it'll return the scan code of the key, and the second it'll return a 0 byte.
What's happening in your code is that you're reading the scan code, printing something appropriately, then _kbhit is returning true again, so you read the '\0' byte, set b to '\0', and then (since you don't have any code to do anything when b is 0) you (repeatedly) do nothing until the next time the user presses a key.
Reference
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getch-getwch?view=vs-2017
It seems like the program behaves the way you want it to. If I press 'w', it goes into an infinite loop of increasing the value of c and printing it. Pressing any other key stops printing and pressing 'c' goes on the same infinite loop and prints hello. Doesn't seem to be any problems as far as the posted code is concerned. Also, I would like to say the same as #Someprogrammerdude, if it compiles, but doesn't behave the way you want it to, it's an issue with the code, not the IDE and/or compiler.
Hypothetical answer: Your computer might always be thinking that a key is pressed, thus kbhit() always returns true. This maybe caused by a bad mouse/keyboard/controller driver and/or configuration. The code is fine, your PC is not.
Today i was testing how key pressing might work in C++ and made simple loop for it,and found that getch() duplicate itself for some reason or idk what is going on honestly,just look at that:
#include <iostream>
#include <windows.h>
#include <conio.h>
#define VK_H 0x48
using namespace std;
int main()
{
int n=1;
int total=0;
bool theEnd=true;
while(theEnd)
{
cout<<total<<endl;
getch();
if(GetAsyncKeyState(VK_LEFT))
{
total -=n;
}else if(GetAsyncKeyState(VK_RIGHT))
{
total +=n;
}else if(GetAsyncKeyState(VK_LSHIFT) && GetAsyncKeyState(VK_F1))
{
total = 0;
} else if(GetAsyncKeyState(VK_ESCAPE))
{
break;
}
}
cout<<total<<endl;
}
Its pretty simple.Program starts with a loop,where endlessly outputs value of variable "total",and after pressing left/right buttons "total" decrements/increments by 1.
Its was worked fine and perfect when i was using system("pause"); Sleep(milliseconds); cin.get();(but this one assume pressing enter each time,so it is not proper one) ,all that output right value on the screen after each pressing on the buttons.But in case with getch(); it somehow appear to working like only one time per/two cycles of the loop.
So the result i've get is like this: i'm pressing button right - current loop working fine,but next one working like without getch(),incrementing and outputting one more time without my command...
I've siting and thinking couple hours,trying find any answers in google and here but nothing...
P.S.without using getch() or other things for purpose stoping loop till next pressing - it will add not +1 to total by single pressing(as i need),but hundreds(average pressing key will do 150-300 loops lol).
From MS documentation
Remarks
The _getch and_getwch functions read a single character from the
console without echoing the character. None of these functions can be
used to read CTRL+C. When reading a function key or an arrow key, each
function must be called twice; the first call returns 0 or 0xE0, and
the second call returns the actual key code.
When you press arrow keys, the input is 2 chars
I have created an application for detect pressing up and down key on keyboard
but nothing will be printed after pressing these keys.
I am using Visual C++ 2010
#include <iostream>
#include <conio.h>
using namespace std;
void main()
{
char x;
while(1)
{
x = getch();
if(x==0 || x==224)
{
x=getch();
if(x==80)
{
cout << "down"<<endl;
}
else if(x==72)
{
cout << "up"<<endl;
}
}//if x==0 || x=224
}//while1
}//main
What can be the problem?
Thanks
Just to answer why it isn't working: You are trying to use your user's input as unsigned. Your character variable is signed so the value is different than you are expecting. An unsigned 224 is a signed -32.
As far as your loop goes I'd suggest changing things to this.
void main()
{
char x;
while(true)
{
while(!kbhit()){}
x = getch();
if(x==0 || x==-32)
{
x=getch();
if(x==80)
{
cout << "down"<<endl;
}
else if(x==72)
{
cout << "up"<<endl;
}
}//if x==0 || x=224
}//while1
}//main
The program will still loop forever. Then the next loop, which I added, will continue to loop while there are no keys being pressed(buffered). Then getch() grabs the next char from the buffer. Now the problem you were running into, is that you had 224 (0xE0) which is technically correct. However in binary apparently -32 and 224 look the same.
I ran into a bit of the same issue at first, I couldn't figure out why my code wasn't hitting the correct code block and it was because the first character was actually -32 (0xE0)
Hope that is of some help, despite this being a really old question.
You can use the curses.h library. Read their guide and it should be very easy from there.
After you take input using getch() (store the input into an int, not a char), you can verify if it's one of the arrow keys using the defined keycodes. Just make sure you used keypad(stdscr, TRUE) before for the program to be able to recognize the arrow keys.
Us kbhit() to get Keyboard Arrow Keys