I am making a game which has a character moves in 4 directions: up, down, left, right corresponding to W,S,A,D on the keyboard. The problem is when using getch() to get input from buffer, it always has a pause time after the first single keypress. For instance, when I hold 'A' button, it acts like: A(a short period of time)AAAAAAAAA.
How do I get rid of that delay time?
Any help would be appreciated.
(Answers in either C or C++ are all acceptable, since I am using graphics.h for this program, which requires C++ to run, but I mainly code in C).
I am using windows 10 64 bits.
For a non-blocking getch method I personally use this piece of code (in C):
#include <conio.h>
int getch_noblock(){
return _kbhit() ? _getch() : -1;
}
the _kbhit() method returns 0 if no key are pressed, otherwise returns a number if the keyboard input buffer is not empty.
the _getch() method read a char from the keyboard buffer.
It works only for Windows.
Documentation:
_khbit(): https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/kbhit?view=msvc-170
_getch(): https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getch-getwch?view=msvc-170
By the way, surfing on the web I found an interesting method, but I've never tried or seen it:
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getch-nolock-getwch-nolock?view=msvc-170
getch() already bypasses buffer:
Prototype
int _getch(void);
Description
_getch obtains a character from stdin. Input is unbuffered, and this
routine will return as soon as a character is available without
waiting for a carriage return. The character is not echoed to stdout.
_getch bypasses the normal buffering done by getchar and getc.
And for your problem, as someone already said, you can use the kbhit() method
Related
I have just started learning c++ and I want the programme to stay open after the result is displayed. So I used getch(); and c++ is showing that it should have a prototype. What does it mean? and how do I resolve this>
it means one of the followings:
you are programming under DOS and forgot to include conio.h (https://en.wikipedia.org/wiki/Conio.h). Possibly you copied a source from an older textbook, since conio.h is a very old concept. What sources do you use for learning? I'd recommend one from: The Definitive C++ Book Guide and List
You are programming under Linux and you forgot to include curses.h (http://linux.die.net/man/3/getch)
Include:
1) <conio.h> on Windows.
2) <curses.h> on UNIX
Looks like you only want to PAUSE your console application on the screen. Use this#include <stdio.h> and try getchar(); instead of getch(); or simply system("pause"); or cin.ignore() will do the job for you.
Also, "Start without Debugging" using Ctrl-F5 will allow you to Press Any Key To Continue at the end of your program. This way it won't close until you press some key and the console will pause on the display screen.
If you're on Windows then getch is a function from the Windows-only <conio.h> library. You need to include it (#include <conio.h>).
It's possible only on Windows.
Also, getch() is deprecated.
Use _getch() instead.
If you're on GNU+Linux, then getch is a function from the <curses.h> library. You need to include it (#include <curses.h>).
The objective as I understand is :
I want programme to stay open after the result is displayed
Why not do it the typical c++ way?
#include<iostream>
int main(void)
{
int i;
char ch;
std::cout<<"Enter any character : ";
std::cin.get(ch); // For testing enter a string at this step say "String"
/* The input to cin is line-buffered, so after reading 'S' to ch,
* the remaining "tring" is still in the buffer.
*/
std::cout<<"Entered character : "<<ch<<"\n";
while(std::cin.get()!='\n')
;;
/* cin.get() is an overloaded function in the istream class.
* If no arguments are passed to 'get()' this function reads single next character
* In essence, we wait for the cin.get() to clear the buffer that is
* read all characters including '\n'
*/
std::cout<<"Press any key to continue..\n";
std::cin.get();
/* Since we have already cleared the buffer using the loop
* 'get()' expects us to enter a character this time
*/
return 0;
}
The following is my code, that I want to read characters from stdin, and end when it meet an EOF(ctrl-z).
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<string>
using namespace std;
int main()
{
string article ;
char nextChar;
while( cin.get(nextChar) ) {
if( cin.eof() ) break ;
article.append(1, nextChar) ;
}
cout << article ;
system("pause") ;
}
I test an input like this:
I am a student.<ctrl-z>
And then I press enter, but it does not halt.
When I type another [ctrl-z], and then press neter.
It just can exit from the while loop.
Why the first [ctrl-z] not to signal the eof condition?
The following explanation is slightly simplified.
It's a feature of your operating system. This is how your operating system works.
An end of file is, really, the underlying read() system call returning 0. An end of file is not CTRL-Z. CTRL-Z gets interpreted by your operating system to flush its interactive key buffer, and have the process read() its contents.
When you type in a terminal, the process does not actually end up reading anything until Enter is pressed. At that time the read() system call completes, and returns everything that's been read. In general, before pressing Enter you can backspace and edit what you typed, and your program has no indication that you've edited anything, all that it read()s is the final contents of the line after pressing Enter.
If you type something, and press CTRL-Z, the typed input is also read() by the program as if it was typed in.
Only if nothing is typed, and CTRL-Z is pressed, does the underlying read() system call returns 0, because nothing got typed in first; this is interpreted as an end-of-file indication. But if something gets typed in first, CTRL-Z needs to be entered twice, once to read() the typed in input, and clear the input buffer, then CTRL-Z a second time, to cause an read() of 0.
By the way, your code has a harmless bug. If cin.get() succeeds, cin.eof() can never be true.
I am trying to use the c++ standard input stream cin to get a user input without blocking the execution of the program. I have this code:
char ch;
int flag=1;
do
{
if(cin.rdbuf()->in_avail())
{
cin.get(ch);
flag=0;
}
else
//do something else
}while(flag);
//do something with the input
The idea here is to wait for user input without blocking while doing something else and as soon as the user provides an input we process the input( all in one thread). I know from the documentation the streambuf class used by the input stream provides the in_avail() function which will return a non-zero values when ever there is input ready in the buffer. The code above is not working as i expected it and is looping forever even if i provide a keyboard input at some point. i am using MS visual studio 2005 in windows 7. what am i missing here?
The function in_avail does:
Returns the number of characters available in the get area.
The get area may be empty even if some characters are readable from the underlying operating system buffer.
You will trigger a refill of the get area when you effectively call a read operation on the streambuf. And that operation will block. The reason is that the method underflow which is responsible for filling the get area:
Ensures that at least one character is available in the input area
And to ensure this, it must block until some character is read.
I am new to c++ ,
What code should i write to make the screen stand still. I use
getche();
in c language. but instead of getche() what should i use in c++;
I tried
std::cin.get();
but the console windows displays and then goes off quickly.
the console windows displays and then goes off quickly.
It seems that you have something in your buffer, and cin.get is reading that as a character. For example:
int i = 0;
std::cin >> i;
std::cin.get();
When you enter number and press Enter, cin >> i will consume the number, but it will leave \n character (which comes from Enter keystroke) in the buffer which will be read by std::cin.get() without waiting for the user to enter new data.
In order to make this example to behave like we want, we need to empty the buffer before calling std::cin.get():
int i = 0;
std::cin >> i;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
std::numeric_limits is defined in <limits> header file.
In Windows, I usually uses system("pause");, which call the OS's pause command, to prevent the console window from being closed after the program terminates. This commands displays a nice message and wait for any key :).
Press any key to continue . . .
I don't know if the command exists in the other OSes or not, nor I don't know if it is what you're trying to archive :).
The function is in the cstdlib or stdlib.h header file
Last but not least, it's not really a good idea to call getch() at the last line of code to prevent the console from being closed. But if you really prefer this way, I suggest to use something like
std::string temp;
std::cin>>temp;
At the ends of your main function, just before return statement.
Just include <stdlib.h> and in main method use system("pause") your console window will remain still.
Please use the following
getch()
I one part of my application I have used Sleep(5000) (I need to wait 5 sec)
The problem is that if the user presses any keyboard key during these 5 seconds, the keys will be read after sleep and it causes problems for my app.
How can I empty the buffer after sleep?
I tried cin.clear() and setbuf(stdin, NULL) but they can't clear the buffer if there is more than one character in the buffer.
The two functions you are using don't have the effect you expect them to have:
clear() doesn't affect the buffer at all but rather clears the error flags. That is, if there was an unsuccessful read a flag is set (std::ios_base::failbit). While any error flag is set (there are a few more), the stream won't attempt to read anything.
setbuf(0, 0) affects the stream's internal buffer to not exist (calls with non-null values have implementation-defined meaning which is typically "do nothing"). This is generally a Bad Idea because it causes the streams to be very slow. Also, the keys pressed by a user are probably not stored in this buffer anyway but rather in the operating systems input buffer until they are sent to application (there are platform specific ways to turn off the operating system input buffer, e.g., on POSIX you'd use tcsetattr() to set the input into non-canonical mode).
In either case, not having a buffer doesn't really help you anyway: The user may very well have typed valid input. The proper approach is to attempt reading the available input and, if this fails, to rid of the offending character (or characters). To this end you'd attempt to read the input and if it fails you'd clear() the stream and ignore() one or more characters (this example ignores an entire line; call ignore() without parameters to just ignore one character):
T value;
while (!(std::cin >> value)) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
You always need to verify that the input was successful anyway and the few extra lines are just adding a bit of recovery code.
The simplest way to clear the keyboard input buffer is
while(kbhit()) getch();
just put that code in your program wherever you want to clear your buffer .
headerfile needed for that is conio.h
This seems to work for Windows 10 compiled with Code::Blocks:
#include <conio.h>
/**
* clears keyboard buffer
*
* #author Shaun B
* #version 0.0.2
* #fixed 15-01-2016
*/
void clearKeyboardBuffer()
{
while (_kbhit())
{
_getche();
}
}
Then called from where is needed in your C++ script.