我有一些现有的Visual C ++代码,我需要将宽字符串的转换添加到大写或小写。
我知道这有一些陷阱(比如土耳其语“我”),但如果你懂得语言,大部分都可以解决。幸运的是,在这个代码区域,我知道LCID值(区域设置ID),我想这与知道语言相同。
由于LCID是Windows类型,是否有一个Windows函数可以将宽字符串转换为大写或小写?
C运行时函数_towupper_l()听起来很理想,但它需要一个_locale_t参数而不是LCID,所以我想这是不合适的,除非有一个完全可靠的方法将LCID转换为_locale_t。
答案 0 :(得分:0)
您要搜索的功能称为LCMapString
,它是Windows NLS API的一部分。 LCMAP_UPPERCASE
标志将字符映射为大写,而LCMAP_LOWERCASE
将字符映射为小写。
对于针对Windows Vista及更高版本的应用程序,有an Ex
variant适用于区域设置名称而非标识符,这是Microsoft现在所说的您应该使用的。
事实上,在VS 2010提供的CRT实现中(也可能是其他版本),_towupper_l
之类的函数在从LCMapString
中提取区域设置ID(LCID)之后最终会调用_locale_t
。指定的CharXxx
。
如果你像我一样,并且不太熟悉i8n API,那么你可能已经了解CharUpper
,CharLower
,CharUpperBuff
和{{3函数族。这些都是Windows早期用于改变字符/字符串的旧版本,但正如他们的文档所警告的那样:
请注意
CharXxx
始终将大写字母I映射为小写字母I(“i”),即使当前语言为土耳其语或阿塞拜疆语。如果您需要在这方面具有语言敏感性的功能,请致电CharLowerBuff
。
在迈克尔卡普兰关于国际化问题的精彩博客中,有几篇帖子填写了它忽略的内容:LCMapString
,What does "linguistic casing" mean?。执行摘要是您通过调用LCMapString
和而不是指定LCMAP_LINGUISTIC_CASING
标志来获得与LCMAP_LINGUISTIC_CASING
系列函数相同的结果,而您可以在语言上确保您做指定std::wstring test("Does my code pass the Turkey test?");
if (!LCMapStringW(lcid, /* your LCID, defined elsewhere */
LCMAP_UPPERCASE | LCMAP_LINGUISTIC_CASING,
test.c_str(), /* input string */
test.length(), /* length of input string */
&test[0], /* output buffer (can reuse input) */
test.length())) /* length of output buffer (same as input) */
{
// Uh-oh! Something went wrong in the call to LCMapString, so you need to
// handle the error somehow here.
// A good start is calling GetLastError to determine the error code.
}
标志。
示例代码:
{{1}}