Search code examples
c++11type-conversionasciicurses

how can i safely convert an ascii integer back to its associated ascii character using curses in c++?


I have not been able to find a reliable solution for my problem, what i'm simply trying to do is create some function which:

  • takes an rows and columns position in the terminal.

  • calls mvinch(window_object , rows, cols), which returns an unsigned int which corresponds to the character in the terminal at that position.

  • returns the ascii character associated with that unsigned int, effectively casting it back to a char.

Here is an example of my code in c++11:

char Kmenu::getChrfromW(size_t const y, size_t const x,
                        bool const save_cursor) const {
  size_t curr_y, curr_x;
  getyx(_win, curr_y, curr_x);
  char ich = mvwinch(_win, y, x);
  char ch = ich;
  if (save_cursor)
    wmove(_win, curr_y, curr_x);
  return ch;
}

If for example the character in the terminal at position 2,3 is the letter 'a', i want this function to return the letter 'a'.

I tried the solution described here:

Convert ASCII number to ASCII Character in C

which effectively casts an integer as char.

unfortunately what i get back is still the integer: testing with a screen filled with 'w's, i get back the integer 119.

the man page for the curses function mvwinch() describes the function to return chtype, which the compiler recognises as unsigned int.

Is there a built in a curses function which gives the char back directly without casting to unsigned int, or some other way i can achieve this?

Edit: ch to ich, as in the actual code


Solution

  • A chtype contains a character along with other data. The curses.h header has several symbols which are useful for extracting those bits. If you mask it with A_CHARTEXT and cast that to a char, you will get a character:

    char c = (char)((A_CHARTEXT) & n);
    

    Your example should not compile, since it declares ch twice. You may have meant this:

    char Kmenu::getChrfromW(size_t const y, size_t const x,
                            bool const save_cursor) const {
      int curr_y, curr_x;  // size_t is inappropriate...
      getyx(_win, curr_y, curr_x);
      char ch = (char)((A_CHARTEXT) & mvwinch(_win, y, x));
      // char ch = ich;
      if (save_cursor)
        wmove(_win, curr_y, curr_x);
      return ch;
    }
    

    The manual page for mvwinch mentions the A_CHARTEXT mask in the Attributes section, assuming the reader is familiar with things like that:

       The following bit-masks may  be  AND-ed  with  characters  returned  by
       winch.
    
       A_CHARTEXT     Bit-mask to extract character
       A_ATTRIBUTES   Bit-mask to extract attributes
       A_COLOR        Bit-mask to extract color-pair field information