1

I would like to write a C++ programme on Ubuntu, which reacts immediately to the input without pressing enter. (-> I cannot use the header #include <conio.h> due to the reason that I am working on an UNIX system)

For instance: I press on my keyboard the key "a", but instead of showing "a" in the terminal, the programme should show "p".

For the last two days, I tried to do this with the header #include <ncurses.h>. Unfortunately, it doesn't work.

Therefore, I would like to ask for your request.

With conio.h it would be like this:

#include <iostream> 
#include <conio.h> 
#include <string> 
using namespace std;

int main(void) 
{
    char c;
    c = getch();

    while(true)
    {

        if(c=='a')
        {
        putch('p');
        }

        else
        {
        putch(c);
        }

    c = getch();

    }

  cin.sync();              
  cin.get(); 
}

Can you please simply post the working source code with #include <ncurses.h> instead of #include <conio.h>?

Thank you so much in advance!!!

With best regards

quark42

Thank you Paulo1205!!!!

Here is my final code without conio.h:

#include <iostream> 
#include <string> 
#include <unistd.h>  
#include <termios.h>
#include <ncurses.h>
using namespace std;

int my_getch(void){
  struct termios oldattr, newattr;
  unsigned char ch;
  int retcode;
  tcgetattr(STDIN_FILENO, &oldattr);
  newattr=oldattr;
  newattr.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
  retcode=read(STDIN_FILENO, &ch, 1);
  tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
  return retcode<=0? EOF: (int)ch;
}



int main(void) 
{
    char c;
    c = my_getch();

    while(true)
    {

        if(c=='a')
        {
        putchar('p'); fflush(stdout);
        }

        else
        {
        putchar(c); fflush(stdout);
        }

    c = my_getch();

    }

  cin.sync();              
  cin.get(); 
}
Coding4Fun
  • 81
  • 1
  • 9
  • 1
    There is an implementation of `getch` for Linux, it may help you: http://stackoverflow.com/questions/7469139/what-is-equivalent-to-getch-getche-in-linux – nnn Dec 01 '15 at 16:24
  • And as a replacement for `putch(c);`, you could use `putchar(c); fflush(stdout);` – nnn Dec 01 '15 at 16:31
  • @nnn, I don't like that implementation, since it uses `getchar()` but ignores the possibility of signaling error, since it casts its `int` return type to (possibly signed) `char`, and essentially make `EOF` identical to (possibly valid) char with value `'\xff'` ("ÿ", depending on locale). – Paulo1205 Dec 01 '15 at 16:46
  • OTOH, special keys, such as arrows, function, pgup, etc., as well as accented or graphical characters out of ASCII range are likely to cause trouble. – Paulo1205 Dec 01 '15 at 17:04

1 Answers1

2

If all you want is a quick replacement for the old ConIO getch(), the following code is enough.

int my_getch(void){
  struct termios oldattr, newattr;
  unsigned char ch;
  int retcode;
  tcgetattr(STDIN_FILENO, &oldattr);
  newattr=oldattr;
  newattr.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
  retcode=read(STDIN_FILENO, &ch, 1);
  tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
  return retcode<=0? EOF: (int)ch;
}

However, note that old DOS ConIO is a stripped-down version of UNIX Curses package, which provides everything you need for text terminal screen operations.

EDIT: Curses is most certainly the way to go, anyway. If you ever want to deal with arrow or function keys, without bothering with knowing the escape sequeneces associated with them for each type of terminal, you'd rather learn Curses and its own version of getch().

Also, if you think you'll ever need support for characters out of ASCII range with UTF-8 or any other multibyte representation, you're better-off using ncursesw library's function get_wch() and its sisters.

Paulo1205
  • 918
  • 4
  • 9
  • Dear coders, please allow me to ask one more question to this topic. My programme should also react, when the backspace key will be pressed. What do I need to add / change that it will work with my_getch()? With best regards quark42 – Coding4Fun Dec 01 '15 at 17:59
  • @NewUbuntuUser It depends. It might return the value 8 (ASCII BS; same as typing Control-H), 127 (ASCII DEL) or an arbitrary sequence of special characters (thus requiring you to call the function multiple times, something that ConIO's getch() also required in some occasions), depending on the type of the terminal. This is one of the reasons why you'd rather consider upgrading to Curses' `getch()` or `get_wch()`. – Paulo1205 Dec 01 '15 at 20:11