Search code examples
clinuxkeyboardasciicurses

Weird key values printed by ncurses


I am doing a little program in C with the ncurses library on Linux.

I decided to check the input I received with the getch() function, more specifically, the backspace key.

The backspace ASCII decimal value is 127, link: here I decided to print the numerical decimal value of the keys I pressed, for example:

a -> 97

A -> 65

] -> 93 ...

The latter are correct.

However, the following values are not correct:

Backspace -> 7 (which is BELL)

Supr -> 74 (which is 'J')

Here is the test code:

#include <curses.h>

int main(int argc, char **argv)
{
  char ch;
  int column,line;
  int s_column,s_line;
  initscr();
  clear();
  noecho();
  raw();
  keypad(stdscr,TRUE);
  printw("Type: \n> ");
  refresh();
  getyx(stdscr,s_line,s_column);
  while((ch=getch())!='\n')
    {
      printw("%d",ch);
      addch(ch);
      refresh();
    }
  endwin();
  return 0;
}

NOTE: changing raw() to cbreak() generates the same output

Output test: (note: I type: 'a','A',(Backspace),(Supr),'J')

Type:
> 97a65A7^G74J74J

I don't understand why this is happening, can somebody explain why the Backspace key outputs 7 instead of 127, and Supr outputs 74, which is the same sa 'J'?


Solution

  • For special function keys, getch() doesn't necessarily return the ASCII character, it returns one of the KEY_xxx codes in <curses.h>. In the case of Backspace, this is:

    #define KEY_BACKSPACE   0407        /* backspace key */
    

    Since you declare ch as char rather than int, the value 0407 is being truncated to 07.

    Change the declaration to:

    int ch;
    

    and then it will display 263 when you press Backspace. addch() will still display ^G, though, because it doesn't use the KEY_xxx macros. You need to handle these characters in your code.