For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > June 2005 > getch() and c++









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author getch() and c++
Markus Franke

2005-06-09, 3:58 pm

Hi,

i want to register if the user is pressing the <TAB>-Key in a
c++-program. I know that there is normally no way to do this by
standard c++. I have looked in several newsgroups and tried also
to use curses but without success.
Does anybody have an idea? I only want to register if the key was
pressed. The character should not be printed on stdout.

Thanx for help
Markus Franke
David Schwartz

2005-06-09, 8:58 pm


"Markus Franke" <Markus.Franke@informatik.tu-chemnitz.de> wrote in message
news:slrndah1pj.3i7.Markus.Franke@quax.csn.tu-chemnitz.de...

> i want to register if the user is pressing the <TAB>-Key in a
> c++-program. I know that there is normally no way to do this by
> standard c++. I have looked in several newsgroups and tried also
> to use curses but without success.
> Does anybody have an idea? I only want to register if the key was
> pressed. The character should not be printed on stdout.


This is a variant of a frequently asked question. Google for 'UNIX' and
'kbhit' (a DOS functions that provides a similar capability) and you'll find
a thousand answers.

DS


Markus Franke

2005-06-09, 8:58 pm

Thank you. I have found a solution.

Implementation of getch():

#include <termios.h>

int getch() {
static int ch = -1, fd = 0;
struct termios neu, alt;
fd = fileno(stdin);
tcgetattr(fd, &alt);
neu = alt;
neu.c_lflag &= ~(ICANON|ECHO);
tcsetattr(fd, TCSANOW, &neu);
ch = getchar();
tcsetattr(fd, TCSANOW, &alt);
return ch;
}

Greets
Markus
David Schwartz

2005-06-09, 8:58 pm


"Markus Franke" <Markus.Franke@informatik.tu-chemnitz.de> wrote in message
news:slrndahdsf.3i7.Markus.Franke@quax.csn.tu-chemnitz.de...
> Thank you. I have found a solution.
>
> Implementation of getch():
>
> #include <termios.h>
>
> int getch() {
> static int ch = -1, fd = 0;
> struct termios neu, alt;
> fd = fileno(stdin);
> tcgetattr(fd, &alt);
> neu = alt;
> neu.c_lflag &= ~(ICANON|ECHO);
> tcsetattr(fd, TCSANOW, &neu);
> ch = getchar();
> tcsetattr(fd, TCSANOW, &alt);
> return ch;
> }


You should check the return value of 'tcgetattr'. It's always possible
that stdin is not a terminal, and you'll have to decide what to do in that
case. That is, assuming you haven't already checked that it's a terminal.
Even if you have, additional error checking is a good idea in any case.

DS


Måns Rullgård

2005-06-09, 8:58 pm

Markus Franke <Markus.Franke@informatik.tu-chemnitz.de> writes:

> Thank you. I have found a solution.
>
> Implementation of getch():
>
> #include <termios.h>
>
> int getch() {
> static int ch = -1, fd = 0;


I see no reason to make those static.

> struct termios neu, alt;


This is an English-speaking newsgroup.

> fd = fileno(stdin);
> tcgetattr(fd, &alt);
> neu = alt;
> neu.c_lflag &= ~(ICANON|ECHO);
> tcsetattr(fd, TCSANOW, &neu);
> ch = getchar();
> tcsetattr(fd, TCSANOW, &alt);
> return ch;
> }


--
Måns Rullgård
mru@inprovide.com
Floyd L. Davidson

2005-06-10, 4:00 am

Markus Franke <Markus.Franke@informatik.tu-chemnitz.de> wrote:
>Thank you. I have found a solution.
>
>Implementation of getch():
>
>#include <termios.h>
>
>int getch() {
> static int ch = -1, fd = 0;


Don't make these static, and there is no need to initialize either of
them.

> struct termios neu, alt;
> fd = fileno(stdin);


Check for error return.

You probably should flush stdout here too, though that
is optional I suppose.

> tcgetattr(fd, &alt);


Check for error return.

Note that what I've always used is slightly different, and I'm not
sure which is actually better, but I do

tcgetattr(STDIN_FILENO, &alt);

> neu = alt;
> neu.c_lflag &= ~(ICANON|ECHO);


In addition to clearing those bits in the c_lflag member,
you need to set values for c_cc[] members VTIME and VMIN
because the could be just about anything.


neu.c_cc[VMIN] = 1; /* block for input */
neu.c_cc[VTIME] = 0; /* timer is ignored */

If you want this to be non-blocking input, use different values.

> tcsetattr(fd, TCSANOW, &neu);
> ch = getchar();
> tcsetattr(fd, TCSANOW, &alt);


Check for errors on all of those. Note that if you block for
input, you may want to call tcsetattr() set to TSCAFLUSH rather
than TCSANOW.

> return ch;
>}


Here's a way to integrate error checking into that. You can
skip error checking on the initial call to tcsetattr(), because
if it fails, so will this last one.

int error;

if (0 == (error = tcsetattr(STDIN_FILENO, TCSANOW, &eu))) {
/* get a single character from stdin */
error = read(STDIN_FILENO, &ch, 1 );
/* restore old settings */
error += tcsetattr(STDIN_FILENO, TCSANOW, &alt);
}

return (error == 1 ? (int) ch : -1 );



--
Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) floyd@barrow.com
Dmitry Mityugov

2005-06-10, 8:57 pm

Måns Rullgård wrote:
> Markus Franke <Markus.Franke@informatik.tu-chemnitz.de> writes:
>
>
> I see no reason to make those static.
>
>
> This is an English-speaking newsgroup.

....

Looking high and low but can't find any evidence of this? Care to give
pointers to FAQs etc?

Dmitry


Måns Rullgård

2005-06-10, 8:57 pm

"Dmitry Mityugov" <dmitry.mityugov@gmail.com> writes:

> Måns Rullgård wrote:
>
> Looking high and low but can't find any evidence of this? Care to give
> pointers to FAQs etc?


When was a non-English message last posted? English certainly seems
to be the de facto language of this group, even if there is no formal
official language.

--
Måns Rullgård
mru@inprovide.com
Barry Margolin

2005-06-11, 3:57 am

In article <d8cqaa$mte$1@news.rol.ru>,
"Dmitry Mityugov" <dmitry.mityugov@gmail.com> wrote:

> Måns Rullgård wrote:
> ...
>
> Looking high and low but can't find any evidence of this? Care to give
> pointers to FAQs etc?


And why is this even an issue? There was no non-English posted in the
thread (unless Mans was referring to the variable names, which hardly
seems worth making a point about).

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Måns Rullgård

2005-06-11, 8:57 am

Barry Margolin <barmar@alum.mit.edu> writes:

> In article <d8cqaa$mte$1@news.rol.ru>,
> "Dmitry Mityugov" <dmitry.mityugov@gmail.com> wrote:
>
>
> And why is this even an issue? There was no non-English posted in the
> thread (unless Mans was referring to the variable names, which hardly
> seems worth making a point about).


I was referring to the variable names, and no, it's not really
anything worth making a point of. There is, however, some reason to
use English variable names in examples. It makes it easier for the
non-German-speakers to understand the code. It also helps the same
readers spot any differences between intended and actual
functionality.

--
Måns Rullgård
mru@inprovide.com
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com