Visual studio 2015 将字符转换为阿拉伯语大写字母
我有以下代码将字母转换为大写:Visual studio 2015 将字符转换为阿拉伯语大写字母,visual-studio-2015,mfc,arabic,toupper,Visual Studio 2015,Mfc,Arabic,Toupper,我有以下代码将字母转换为大写: // make this character upper if(_istalpha(zChar) && !_istupper(zChar)) pMsg->wParam = (WPARAM)_toupper(zChar); 它已经运行多年了。最近,我被要求支持阿拉伯语,我的用户说字母被破坏了。这是因为上面的代码 阿拉伯语告诉我大写字母不适用。我知道我可以测试我的程序设置,看看他们是否使用阿拉伯语,并避免这种代码。但还有别的办法吗 例如,
// make this character upper
if(_istalpha(zChar) && !_istupper(zChar))
pMsg->wParam = (WPARAM)_toupper(zChar);
它已经运行多年了。最近,我被要求支持阿拉伯语,我的用户说字母被破坏了。这是因为上面的代码
阿拉伯语告诉我大写字母不适用。我知道我可以测试我的程序设置,看看他们是否使用阿拉伯语,并避免这种代码。但还有别的办法吗
例如,我知道你首先调用\u tsetlocale
的日期
更新:
找到了此主题,其中提到了区域设置!我会试试的。正如您所发现的,CRT的
toupper
和Win32的CharUpper
等经典转换例程相当愚蠢。它们通常起源于整个世界都被认为是ASCII码的时代
你需要的是语言敏感的转换。这是一个计算成本更高的操作,但也很难正确实现。语言是硬的。因此,如果可能的话,您希望将责任转移到标准库。由于您使用的是MFC,显然您的目标是Windows操作系统,这意味着您很幸运。您可以借助微软本地化工程师的辛勤工作,获得与shell和其他操作系统组件一致性的额外好处
您需要调用的函数是(或者如果您仍然针对Vista之前的平台)。该函数签名的复杂性有力地证明了正确的语言感知字符串处理的复杂任务
- 首先,您需要选择一个区域设置。您通常需要用户的默认区域设置,您可以使用
指定该区域设置,但您可以在此处使用任何需要的内容locale\u NAME\u user\u default
- 对于标志,您需要
。要执行反向操作,您需要使用LCMAP_大写字母| LCMAP_语言_大小写
。这里还有很多其他有趣和有用的选择需要记住LCMAP_LOWERCASE | LCMAP_language_CASING
- 然后,您有一个指向源字符串的指针,其长度以字符(代码单位)为单位
- 以及一个指向接收结果的字符串缓冲区的指针,以及它的最大字符长度(代码单位)
- 最后三个参数可以简单地设置为NULL或0
BOOL ConvertToUppercase(std::wstring& buffer)
{
return LCMapStringEx(LOCALE_NAME_USER_DEFAULT /* or whatever locale you want */,
LCMAP_UPPERCASE | LCMAP_LINGUISTIC_CASING,
buffer.c_str(),
buffer.length(),
&buffer[0],
buffer.length(),
NULL,
NULL,
0);
}
注意,我在这里对缓冲区的内容进行就地转换,因此假设大写字符串的长度与原始输入字符串的长度完全相同。这可能是正确的,但可能不是一个普遍安全的假设,因此您可能希望为此类错误添加处理(ERROR\u unciplement\u BUFFER
)和/或防御性地向缓冲区添加一些额外的填充
如果您喜欢像现在这样使用CRT函数,
\u totoupper\u l
及其朋友是LCMapString
/LCMapStringEx
的包装者。注意\u l
后缀,它表示这些是区域设置感知转换函数。它们允许您传递显式区域设置,该区域设置将在转换中使用。我假设您使用的是UTF-8字符串。在这种情况下,您的代码需要了解UTF-8,即能够考虑多字节字符。例如,如果两字节字符串中的第二个字符恰好与字母“c”的值相同,则代码将提取该字符并将其转换为大写,从而生成完全不同的两字节字符。
看看这个问题:
回答得太好了。今天晚些时候我会试一试。