Capturing a keystroke in C++ - c++

I have been doing some reading, and I see that I can use getch() to get a keystroke. What I have seen is that this is considered bad practice, however I have seen conflicting opinions. I am writing a console application for my class, and would like to be able to move a marker(*) around the screen based on the arrow keys being pressed. Is getch() the right way to go about this, or is there a better method to capture it. I want them to just be able to push the arrow, not need to push enter or anything. I don't need the code specifically, I just want to know if I should avoid getch(), and if so, what functions are there for this type of idea.

getch() is not a standard function in either C or C++. It's found in some obsolete compilers, such as Turbo C and it's also defined in certain commonly used libraries such as curses, but in any case it's a C function, not C++. For C++ you should probably just stick with standard C++ I/O. If you can't do this for some reason then go for the most portable option, e.g. curses.

You want to read from the terminal in non-canonical mode. Use tcsetattr() to turn off the ICANON flag.

Use getch() if it works. Why not?

On Windows you can use pdcurses: http://pdcurses.sourceforge.net/, that is compatible with ncurses.

Related

C++: User input gives unwanted behaviour

When I use the normal std::cin or std::cin.get() or std::getline() functions, I get unwanted (but understandable) behaviour.
When you use the arrow keys to move back for example, you don't move back, but you input something like "^[[D" into the console.
Is there a way to make the std input function more like, let's say the Python terminal environment?
Thanks in advance!
No, you cannot do it with the standard library. The only approximation is outputting the backspace character \b and hope it does the right thing in the user's environment.
You will need to use either system APIs or libraries like readline or ncurses.

How to control stdin echo in C++?

In Linux, I can use tcsetattr, but I want to write a portable C++ program that can turn echo of cin on and off (for entering a password). Is there something in std::io* that supports this?
Unfortunately there is no portable way to disable console echo, so you have to use OS specific API. You can use preprocessor to write portable program, but you would have to write separate code for supported OS and wrap it into #ifdef condition. Another solution would be to use portable library if such one exists, that would do this under the hood for you.
No, there is not. C/C++'s IO libraries are based around the "stream" model, where input comes from some random source of characters (generally the console) and output is similarly sent to some random character target. In a sense, it isn't C/C++ doing the echoing at all -- it's the console system -- so there's no way for it to control whether the echoing occurs.

What should i do if i want to use functions that are not standard and are due to compiler specific API?

I have been using the very very old Turbo C++ 3.0 compiler.
During the usage of this compiler, I have become used to functions like getch(), getche() and most importantly clrscr().
Now I have started using Visual C++ 2010 Express. This is causing a lot of problems, as most of these functions (I found this out now) are non-standard and are not available in Visual C++.
What am I to do now?
Always try to avoid them if possible or try their alternatives :
for getch() --- cin.get()
clrscr -- system("cls") // try avoiding the system commands. check : [System][1]
And for any others you can search for them .
The real question is what you are trying to do, globally.
getch and clrscr have never been portable. If you're trying
to create masks or menus in a console window, you should look
into curses or ncurses: these offer a portable solution for
such things. If it's just paging, you can probably get away
with simple outputing a large number of '\n' (for clrscr),
and std::cin.get() for getch. (But beware that this will only
return once the user has entered a new line, and will only read
one character of the line, leaving the rest in the buffer. It
is definitely not a direct replacement for getch. In fact,
std::getline or std::cin::ignore might be better choices.)
Edit:
Adding some more possiblities:
First, as Joachim Pileborg suggested in his comment, if
portability is an issue, there may be platform specific
functions for much of what you are trying to do. If all you're
concerned about is Windows (and it probably is, since system(
"cls" ) and getch() don't work elsewhere), then his comment
may be a sufficient answer.
Second, for many consoles (including xterm and the a console
window under Windows), the escape sequence "\x1b""2J" should
clear the screen. (Note that you have to enter it as two
separate string literals, since otherwise, it would be
interpreted as two characters, the first with the impossible hex
value of 0x1b2.) Don't forget about possible issues of
redirection and flushing, however.
Finally, if you're doing anything non-trivial, you should look
into curses (or ncurses, they're the same thing, but with
different implementations). It's a bit more effort to put into
action (you need explicit initialization, etc.), but it has
a getch function which does exactly what you want, and it also
has functions for explicitly positionning the curser, etc. which
may also make your code simpler. (The original curses was
developed to support the original vi editor, at UCB. Any
editor like task not being developed in its own window would
benefit enormously from it.)
Well,
People, i have found the one best solution that can be used everywhere.
I simply googled the definitions of clrscr() and gotoxy() and created a header file and added these definitions to it. Thus, i can include this file and do everything that i was doing prior.
But, i have a query too.
windows.h is there in the definition. suppose i compile the file and make a exe file. Then will i be able to run it on a linux machine?
According to me the answer has to be yes. But please tell me if i am wrong and also tell me why i am wrong.

Console overwriting like top

Ok so I was just wondering how console applications like top(1) for linux overwrite multiple lines. I want to know how to do it for C++ or C. I know how to overwrite 1 line by just putting a \r but I wanted to know how to do so for multiple lines, again like in top or if its even possible.
They use terminal escape sequences to move the cursor around the screen. A few even use direct framebuffer access, to treat the screen as an array of characters which can be directly indexed.
The curses (or ncurses) library is a good abstraction layer.
This may not directly address the question, but this sort of thing is dependent on the terminal and is commonly done with a curses implementation (ncurses is the most widely used).

C++, monitor for keyboard input

I'm brushing up on my general programing skills and I've come across a snag. I'm writing a program that simulates a colony of bunnys. Once this program starts it is autonomous, however, at any point the user should be able to press the 'k' key to cull the population by half. I can't think of a way to do this without pausing the program to wait for user input. Nor can I think of a way to make it so that the program will respond immediately (the program runs in semi-real time using the sleep command). Is there a way to accomplish this without multi-treading and years more experience?
I think this article comes close to what you want to do w/o involving ncurses.
C++ doesn't know anything about keyboards, so any answer to this depends on your operating system and its libraries.
Take a look # the GetAsyncKeyState Windows API call. You should be able to find a suitable place to shoehorn this into your code to detect the keypress.
I'm not sure if this is standard C++, but you can use a C function that checks whether a key is available:
#include <conio.h>
int wmain()
{
if(_kbhit())
{
char ch = _getch();
}
}
EDIT: as Zan Lynx mentioned, this is not standard C++, or even standard C, which is why there is no header. It will work fine in Visual C++ or DOS C++ compilers.
A library like Qt can help you quite a bit. You would create an "application" object, derived from QCoreApplication. In your override of QCoreAPplication::event(Event*), you would handle the event if it's a QKeyEvent containing Qt::Key_K. This is portable across Windows, Mac and Linux.
Try ncurses it's pretty standard in UNIX enviorments. It has special functions to wait for user input with timeout in case nobody press any key.