On Fri, 22 Nov 2013 08:50:44 -0800 (PST), �� Tiib <
oot...@hot.ee>
wrote:
>On Friday, 22 November 2013 18:25:07 UTC+2, Geoff wrote:
>> The Microsoft _getch() function gets a character from the console
>> without echo. It does not require a carriage return. It returns the
>> character (int) read and does not have an error return. This makes it
>> very handy for console applications that want to wait for a single
>> keystroke from the user or for password inputs where echo is
>> problematic.
>>
>> Is there a replacement for this non-standard function in C++?
>
>No.
That's unfortunate.
>
>> std::cin.ignore() and std::cin.get() fail as direct replacements since
>> they require the enter key and not just any key be pressed.
>>
>> Solutions involving ncurses or unistd.h are unsatisfactory for the
>> same reason conio.h is unsatisfactory.
>
>Why?
Why are they unsatisfactory? Because they are equally non-standard C++
and non-portable. (Yes, I realize console I/O is intimately connected
to the implementation, which is why _getch exists. It's an ancient
MS-DOS'ism that stems from Borland and Lattice C and is an artifact of
Microsoft backward compatibility.)
>When you do not have something then you write
>the function you need on platform that lacks it using what it
>has.
I was trying to avoid reinventing the wheel.
>It is often just a couple of lines of code and internet is
>probably full of examples.
>For example there is <termios.h> on Linux:
>
>// written in common subset of C and C++:
>#include <stdio.h>
>#include <termios.h>
>static struct termios old, new;
>
>char _getch(void)
>{
> tcgetattr(0, &old); /* grab old terminal i/o settings */
> new = old; /* make new settings same as old settings */
> new.c_lflag &= ~ICANON; /* disable buffered i/o */
> new.c_lflag &= ~ECHO; /* set echo mode */
> tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */
> char ch;
> ch = getchar();
> return ch;
> tcsetattr(0, TCSANOW, &old); /* Restore old terminal i/o settings */
>}
>
>Wrote that plus header and you can use your '_getch()'-using code without
>changes on Linux.
I was aware of this code and was considering using it, thanks for
validating my suppositions about this. The above example is flawed,
however. The functions return int, not char.
int _getch(void)
{
struct termios oldattr, newattr;
int ch;
tcgetattr( STDIN_FILENO, &oldattr );
newattr = oldattr;
newattr.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
return ch;
}
My goal is less about OS portability and more about standardizing the
code but this will have to do, I suppose.