【问题标题】:convert case of wide characters, given the LCID (Visual C++)在给定 LCID (Visual C++) 的情况下转换宽字符的大小写
【发布时间】:2012-01-10 13:19:29
【问题描述】:

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

我知道这有一些陷阱(例如土耳其语的“I”),但如果您了解该语言,其中大部分都可以解决。幸运的是,在这部分代码中,我知道 LCID 值(区域设置 ID),我猜这与了解语言相同。

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

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

【问题讨论】:

  • 你不能使用towuppertowlower吗?
  • 没有。抱歉,我忘记在我的原始帖子中添加对此的评论。 towupper() 的文档说“towupper 的大小写转换是特定于语言环境的。只有与当前语言环境相关的字符才会更改。没有 _l 后缀的函数使用当前设置的语言环境。这些函数的版本带有_l 后缀将语言环境作为参数并使用它而不是当前设置的语言环境”。 LCID 可能不是当前语言环境,因此您需要使用 _l 版本并传入适用的 _locale_t 以获得使用该语言环境的可靠结果。

标签: windows visual-c++ uppercase lowercase lcid


【解决方案1】:

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

对于面向 Windows Vista 及更高版本的应用程序,an Ex variant 适用于语言环境名称而不是标识符,微软现在说你应该更喜欢使用标识符。

事实上,在 VS 2010(可能还有其他版本)提供的 CRT 实现中,_towupper_l 等函数在从指定的 @987654336 提取区域设置 ID (LCID) 后最终会调用 LCMapString @。

如果您像我一样,对 i8n API 的熟悉程度低于应有水平,那么您可能已经了解 CharUpperCharLowerCharUpperBuffCharLowerBuff 系列函数。这些是 Windows 早期用于更改字符/字符串大小写的旧备用设备,但正如他们的文档所警告的那样:

请注意,CharXxx 始终将大写 I 映射到小写 I(“i”),即使当前语言是土耳其语或阿塞拜疆语也是如此。如果您需要在这方面对语言敏感的功能,请致电LCMapString

Michael Kaplan 关于国际化问题的精彩博客中的几篇文章填补了它忽略提及的内容:What does "linguistic casing" mean?How best to alter case。执行摘要是通过调用LCMapString 指定LCMAP_LINGUISTIC_CASING 标志,您可以获得与CharXxx 系列函数相同的结果,而您可以通过确保您在语言上敏感做指定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.
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 2011-02-20
    • 2018-03-28
    相关资源
    最近更新 更多