Hi Everyone,

I know conio.h is not available in Unix. I want to use getch(). Using curses.h needs causes the screen to clear which I don't want.

I found a code snippet (source : internet) using termios, it works, the thing is I need to press enter/or any other key thrice...

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch ( void ) 
{
  int ch;
  struct termios oldt, newt;
  
  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
  
  return ch;
}

Any help on this would be of great help...

Dani AI

Generated

A short, practical diagnosis and next steps that build on the thread

The symptom you saw on HP-UX (having to hit Enter extra times) is consistent with the terminal running in noncanonical mode but using implementation-dependent control-character defaults; the terminal driver decides when a read completes based on the c_cc array (VMIN/VTIME), so different Unix variants can behave differently until those slots are set explicitly. (man7.org)

Two common pitfalls and fixes: (1) stdio input functions like getchar() sit on top of the stdio buffer, which can interact with terminal-mode changes — using the low-level read() on STDIN_FILENO avoids stdio buffering surprises when you switch to noncanonical mode; (2) explicitly set the VMIN/VTIME semantics for the mode you want (for example, “return after one byte” vs. “timeout”), and restore the original attributes on exit. The standard man pages document both the buffering behavior and why read is the pragmatic choice here. (man7.org)

Practical checklist (portable and robust)

  • Verify stdin is a tty (isatty) before changing attributes.
  • Save the original termios, change local flags to clear ICANON/ECHO, set the c_cc VMIN/VTIME behavior you need, and call tcsetattr with the appropriate action (TCSANOW/TCSAFLUSH) depending on whether you need to flush queued input. (man7.org)
  • Read raw bytes with read() (not getchar()), handle EINTR, and always restore the saved termios on normal exit and from signals (use atexit and simple signal handlers). For a complete pattern and example workflow see the GNU libc noncanonical-mode example. (gnu.org)

This ties together 's original termios approach, 's note about flushing stdout (that applies to output buffering), and /'s focus on tcgetattr/tcsetattr; the key extra step on HP-UX/AIX is to set the VMIN/VTIME policy and use read() so the terminal delivers single characters exactly when you expect them.

Recommended Answers

All 9 Replies

Can you show a small program where you call mygetch, and you have to press return twice

Hi Everyone,

I know conio.h is not available in Unix. I want to use getch(). Using curses.h needs causes the screen to clear which I don't want.

I found a code snippet (source : internet) using termios, it works, the thing is I need to press enter/or any other key thrice...

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch ( void ) 
{
  int ch;
  struct termios oldt, newt;
  
  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
  
  return ch;
}

Any help on this would be of great help...

This exact code works for me perfectly

Hi,
Please find the code snippet...

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch ( void )
{
  int ch;
  struct termios oldt, newt;

  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );

  return ch;
}

int main()
{
	char ch;

	ch = mygetch();

	printf("\n Entered Character : %c",ch);

	return EXIT_SUCCESS;
}

I have to press enter twice only then the character gets printed.
One more instance...

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch ( void )
{
  int ch;
  struct termios oldt, newt;

  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );

  return ch;
}

int main()
{
	char ch;

	printf("\n Hello World");
	printf("\n Press any key to continue...");
	mygetch();

	return EXIT_SUCCESS;
}

Here also I need to press enter twice only then the second message gets displayed "Press any key to continue..."

Platform : HP-UX

Any suggestions would be of great help...

Thank You

if the function returns an int what do you think the variable that stores that value should be in main?
Either terminate the literal string in printf with a \n or make a call to fflush(stdout) after.
Otherwise there's not guarantee that it will display when you want.
A call to exit() requires the inclusion of the standard header file stdlib.h

I tried flushing the outpur stream... but no luck... I still need to press enter thrice... i did a gdb and found out that at this line ch = getchar() the program waits for extra two more enter to be pressed...

Is there something to do with the terminal settings?... I tried this in FreeBSD, its working fine... but in HP-UX, AIX its not and it is there where I want to use...

Guys, any suggestions?

Without access to your platform, I've got nothing.

Apart from reading the manuals very carefully.
Focus on tcsetattr, tcgetattr and termios.

There may be some other thing you have to call, possibly right at the start of the program before you do any I/O (including printf).

Finding a forum specific to your platform may also help, if there is such a thing.

Hi Salem,
I am using HP-UX machine...
Yes I am searching other forums also, nothing helps... Hope to get around this somehow...

Hi All,

newt.c_cc[VMIN] = 1;
newt.c_cc[VTIME] = 0;

need to set this... it worked and thanks a lot to frk who helped me in this...

commented: Well done, and thanks for the update for the solution. +22
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.