2012-01-10 24 views
1

我有一些现有的Visual C++代码,我需要将宽字符字符串转换为大写或小写。宽字符转换大写字母给定LCID(Visual C++)

我知道这个(如土耳其语“I”)有一些缺陷,但如果你知道这种语言,大多数这些都可以被消除。幸运的是,在这段代码中,我知道LCID值(区域设置ID),我认为这与知道语言相同。

由于LCID是Windows类型,是否有Windows函数可以将宽字符串转换为大写或小写?

C运行时函数_towupper_l()听起来像是理想的,但它需要一个_locale_t参数而不是LCID,所以我猜这是不合适的,除非有一种完全可靠的方法将LCID转换为_locale_t。

+0

你就不能使用'towupper'或'towlower'? – 2012-01-10 13:39:02

+0

不对不起,我忘了在原始文章中添加评论。对于towupper()的文档说:“towupper的大小写转换是语言环境特定的,只有与当前语言环境相关的字符才会改变,没有_l后缀的函数使用当前设置的语言环境。 _l后缀以区域设置作为参数,并使用该参数代替当前设置的区域设置“。LCID可能不是当前的语言环境,因此您需要使用_l版本并传递适用的_locale_t以使用该语言环境获得可靠的结果。 – appleton 2012-01-10 13:46:09

回答

0

您正在搜索的函数被称为LCMapString,它是Windows NLS API的一部分。 LCMAP_UPPERCASE标志将字符映射为大写,而LCMAP_LOWERCASE将字符映射为小写。

对于面向Windows Vista和更高版本的应用程序,有an Ex variant可以处理区域设置名称而不是标识符,这正是Microsoft现在说的你应该更喜欢使用的名称。

事实上,在具有2010 VS(大概其它版本以及)的CRT实现中,功能如_towupper_l最终最终调用LCMapString后它们提取从指定_locale_t区域设置ID(LCID)。

如果你像我一样,并与i8n的API不太熟悉的比你应该是,你可能已经知道了CharUpperCharLowerCharUpperBuffCharLowerBuff家庭的功能。这些一直是从Windows早期的旧备用的改变字符/字符串的情况下,但由于它们的文档警告说:

注意CharXxx始终映射大写字母I为小写I(“我”),甚至当前的语言是土耳其语或阿塞拜疆语。如果您需要这方面的语言敏感功能,请致电LCMapString

它所忽略不提是由一对夫妇迈克尔·卡普兰的精彩博客文章充满对国际化问题:What does "linguistic casing" mean?How best to alter case。执行摘要是通过调用LCMapString指定LCMAP_LINGUISTIC_CASING标志,而你可以通过确保您指定LCMAP_LINGUISTIC_CASING标志语言敏感达到相同的结果CharXxx家庭的功能。

示例代码:

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. 
} 
相关问题