CroCo
CroCo

Reputation: 5741

When it is safe to use `isalpha()`

I have GLFW key_callback() and I'm trying to detect if an alphabetic character is pressed. I use this function isalpha(). I've noticed that some keys such as Shift and Alt are treated as alphabetic characters if I perform the following code:

#include <iostream>                                                                                                                                                                                         

int main()
{
    // 340: printed int if the Shift key is pressed.
    if( isalpha(340) )
        std::cout << "alpha"     << std::endl;
    else
        std::cout << "not alpha" << std::endl;

    return 0;
}

The preceding code yields alpha. I can validate the range of integers that are passed to the function but this makes no sense since I'm not taking advantage of the function. My question is is it safe to pass any integer to that function and use simple if-statement to validate alphabetic characters? What is the precaution need to be taken if any in case using this function?

Upvotes: 1

Views: 357

Answers (2)

Adrian McCarthy
Adrian McCarthy

Reputation: 48019

key_callback is not a standard part of C++, so I searched and assume that the one you're talking about is part of the GLFW library. In that library, the key_callback gives a keyboard scancode.

Scancodes are not characters. In a typical input model, there's a state machine that maps scancodes (and sequences and combinations of scancodes) to characters. This is the layer that would allow you to change your QWERTY keyboard to work like a Dvorak keyboard or like one designed for typing in another language. This key_callback is lower level, and leaves the mapping to you.

The C++ std::isalpha function takes a char cast to an int or a special sentinel value EOF, which is typically -1. (On some systems, you'll find that you need to first cast your char to an unsigned char before converting it to an int.) Scancodes are not chars, so passing a scancode to std::isalpha is meaningless.

In particular, the value 340 is outside the range of an unsigned char, and it's not EOF, so it really can't be expected to do anything sensible.

If you need chars, you will have to build your own mapping from scancodes (and combinations of scancodes) to chars. It looks like that library has constants defined for the scancodes. For example, GLFW_KEY_LEFT_SHIFT is 340. That should help. If you just need to know if a particular key is pressed or released, you can compare the scancodes to the appropriate constants.

Note: You tagged the question C++, but you linked to the documentation for the C version of isalpha.

Upvotes: 2

Walter
Walter

Reputation: 45474

Just to summarize the wisdom from the discussion in the comments into a short answer.

  1. Your code has undefined behaviour (UB), for reasons discussed in the comments.
  2. Therefore, the outcome is unpredictable and most likely incorrect.
  3. Code with with UB should be avoided as much as possible.

It's not clear what you mean by safe. It's unlikely that it will immediately lead to disaster, but UB in some important code (such as a program controlling an airplane) can do.

Upvotes: 1

Related Questions