2017-05-27 70 views
1

我有GLFWkey_callback()我试图检测是否按字母字符。我使用这个功能isalpha()。我注意到,某些键如Shift和Alt如字母字符,如果我执行以下处理的代码:当安全使用`isalpha()`

#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; 
} 

前面的代码收率alpha。我可以验证传递给函数的整数范围,但这没有意义,因为我没有利用函数。 我的问题是否可以将任何整数传递给该函数并使用简单的if语句验证字母字符?在使用此功能的情况下,需要采取何种预防措施?

+4

我不明白你的代码中的评论。你从哪里得到这个魔法340? –

+13

*行为是不确定的,如果ch的值不能表示为unsigned char或不等于EOF。*这是不确定的行为,你是诱导。 – t0mm13b

+0

@ t0mm13b它说,但它实际上是不确定的?在这种情况下这将是340%256 == 84,即t内显然是字母 –

回答

2

key_callback不是C++的标准部分,所以我搜索并假设你所说的那个是GLFW库的一部分。在该库中,key_callback给出了键盘扫描码。

扫描码不是字符。在典型的输入模型中,有一个状态机将扫描码(以及扫描码的序列和组合)映射到字符。这是允许您更改QWERTY键盘以使其像Dvorak键盘一样工作的层,或者是用于键入另一种语言的设计。这key_callback是较低的级别,并将映射留给你。

的C++ std::isalpha函数采用一个char强制转换为int或特殊标记值EOF,这通常是-1。 (在某些系统上,您会发现在将其转换为int之前,您需要先将char转换为unsigned char。)扫描码不是字符,因此将扫描码传递给std::isalpha毫无意义。

特别值340超出了unsigned char的范围,它不是EOF,所以它真的不能做任何明智的事情。

如果你需要字符,你将不得不建立自己的从扫描码(和扫描码组合)到字符的映射。它看起来像库为扫描码定义了常量。例如,GLFW_KEY_LEFT_SHIFT是340.这应该有所帮助。如果您只需要知道是否按下或释放了某个特定的键,则可以将扫描码与适当的常量进行比较。

注意:您所标记的问题C++,但您链接到为isalpha C版本的文档。

+0

充分的细节。谢谢。 – CroCo

1

只是将评论中的讨论中的智慧总结为一个简短的答案。

  1. 由于在评论中讨论的原因,您的代码有undefined behaviour(UB)。
  2. 因此,结果是不可预测的,很可能是不正确的。
  3. 尽可能避免使用UB代码。

你不明白你的意思是safe。这不太可能会立即导致灾难,但是UB在一些重要的代码(例如控制飞机的程序)中可以做到。