当使用'isalpha()'是安全的

When it is safe to use `isalpha()`

本文关键字:安全 isalpha      更新时间:2023-10-16

我有 GLFWkey_callback(),我正在尝试检测是否按下了字母字符。我使用这个函数是阿尔法()。我注意到,如果我执行以下代码,某些键(例如 Shift 和 Alt)被视为字母字符:

#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 语句来验证字母字符是否安全?在使用此功能时需要采取哪些预防措施?

key_callback

不是C++的标准部分,所以我搜索并假设您正在谈论的是GLFW库的一部分。 在该库中,key_callback提供键盘扫描码。

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

C++std::isalpha函数将char转换为int或特殊哨兵值EOF,通常为 -1。 (在某些系统上,您会发现需要先将char转换为unsigned char,然后再将其转换为int。 扫描码不是字符,因此将扫描码传递给std::isalpha是没有意义的。

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

如果您需要字符,则必须构建自己的从扫描码(和扫描码组合)到字符的映射。 看起来该库具有为扫描码定义的常量。例如,GLFW_KEY_LEFT_SHIFT为 340。 这应该会有所帮助。 如果您只需要知道是按下还是释放了特定键,则可以将扫描码与适当的常量进行比较。

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

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

  1. 由于注释中讨论的原因,您的代码具有未定义的行为 (UB)。
  2. 因此,结果是不可预测的,很可能是不正确的。
  3. 应尽可能避免使用 UB 的代码。

不清楚你说的safe是什么意思.它不太可能立即导致灾难,但一些重要代码中的UB可以做到。