当使用'isalpha()'是安全的
When it is safe to use `isalpha()`
我有 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
的文档。
只是为了将评论中讨论的智慧总结为一个简短的答案。
- 由于注释中讨论的原因,您的代码具有未定义的行为 (UB)。
- 因此,结果是不可预测的,很可能是不正确的。
- 应尽可能避免使用 UB 的代码。
不清楚你说的safe
是什么意思.它不太可能立即导致灾难,但一些重要代码中的UB可以做到。
- 从不同线程使用int64的不同字节安全吗
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 通过网络、跨平台传递std::变体是否安全
- 在std::thread中,joinable()然后join()线程安全吗
- 使用std::istream::peek()总是安全的吗
- 从值小于256的uint16到uint8的Endian安全转换
- 在c++队列中使用pop和visit实现线程安全
- 在类型和包装器之间reinterpret_cast是否安全<Type>?
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 全局变量 多读取器 一个写入器多线程安全?
- 安全到标准:移动会员?
- AcquireCredentialsHandleA() 返回 PFX 文件的0x8009030e(安全包中没有可用的凭据
- 共享队列的线程安全
- boost::文件系统::recursive_directory_iterator多线程安全
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- 当使用'isalpha()'是安全的